keybase / triplesec

Triple Security for the browser and Node.js

Home Page:https://keybase.io/triplesec

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tweaking number of iterations for password/keystretching

rilchr opened this issue · comments

Hi,

I would like to use your library in a kind of hybrid web/mobile app however the key stretching routine takes forever on a mobile device just because generally they have a slower processor and less memory. Can you make the number of iterations configurable? Like pass in a object e.g.

triplesec.encrypt ({
    data:          new triplesec.Buffer('Pssst. I believe I love you.'),
    key:           new triplesec.Buffer('top-secret-pw'),
    iterations:   {  scrypt: 100, pbkdf2: 10 },
    progress_hook: function (obj) { /* ... */ }
}, 

Ideally I would enforce a longer password on my end e.g. 10+ characters and that would offset the need for multiple scrypt and PBKDF2 iterations.

Thanks!

We'd have to update the headers to capture the security parameters.... Doable of course...

Hmm I think you can make it easier on yourself and not update the headers. If my program did the key stretching with a certain set of iterations then that object with the number of iterations is hard coded into my program, I should be able to pass in that same object to the decryption function and get out the right result.

I think if you modify the headers then it gets more complicated and that's catering more for the option where people want to randomly specify the number of iterations per encryption (i.e. dynamically set). I don't really need that. My program can store the number iterations to do in its source code.

commented

Any thoughts on whether this might happen? We are currently using SJCL and would like to switch but I have the same issues as @rilchr above.

Hey guys, thanks for the comments. Whatever parameters are chosen need to be embedded in the output, so the decryptors know which parameters were chosen. Obviously we skirted the issue in v1 through v3 with hard-coding parameters (which by the way I picked to work reasonably well on my phone). The other thing to keep in mind is that you might be encrypting and decrypting on different devices.

commented

It is always a bad sign when someone starts off with "But my product is unique!" but here goes, our product isn't so unique but it does have quite a few seperate bits of data to encrypt and decrypt. I tried using the salt caching technique, and while that helps with encryption, it doesn't help with decryption. We never even made it on to testing on the phone, we could tell from browser tests that it wasn't going to work out for us, unless we could tweak a bit with the iterations and try to up the performance.

Any thoughts on what was mentioned above, pass the same {iterations: XXX} object to decryption, that keeps you from needing to modify the headers. If my app encrypts with certain params, I definitely know which ones I will decrypt with, while it would be "nice" to not have to know them, it would definitely be much less likely scenario that you wouldn't know them.

Ok, let's do this in V4. I'll just set aside 4 bytes of parameters: N, r,
p and log_2(c), where c is the number of PBKDF2 iterations (=1 by default).

I hope to get to this soon, but things are backed up, I'm on a short
paternity leave with little work getting done.

Thanks all

On Thu, Jul 3, 2014 at 3:26 PM, Doug notifications@github.com wrote:

It is always a bad sign when someone starts off with "But my product is
unique!" but here goes, our product isn't so unique but it does have quite
a few seperate bits of data to encrypt and decrypt. I tried using the salt
caching technique, and while that helps with encryption, it doesn't help
with decryption. We never even made it on to testing on the phone, we could
tell from browser tests that it wasn't going to work out for us, unless we
could tweak a bit with the iterations and try to up the performance.

Any thoughts on what was mentioned above, pass the same {iterations: XXX}
object to decryption, that keeps you from needing to modify the headers. If
my app encrypts with certain params, I definitely know which ones I will
decrypt with, while it would be "nice" to not have to know them, it would
definitely be much less likely scenario that you wouldn't know them.


Reply to this email directly or view it on GitHub
#35 (comment).

Let me just be the elephant in the room for a second:
Tweak-able parameters surrounding Scrypt should come with constraints in all implementations and in the spec to prevent attackers from "forcing a downgrade" upon a client. Even using Scrypt it is theoretically possible to set the security so low as to open the resulting keys to ASIC/FPGA/GPU attack.

commented

True, except if they can force a downgrade by hacking your client you have bigger issues as your entire code base is tweakable at that point. If your environment is compromised none of it matters.

[two cents] well, hacking the device from an external source is game over for clients OR servers (ie, ShellShock or HeartBleed or XSS, etc.). [/two cents]
What I'm more concerned about is auto-negotiation of a packet or transport (encrypted with TripleSec) where the negotiation process can be pushed to a lower version number or a really small tweak, and the attacker then sends fishing packets ("here encrypt this for me") and uses that to gain information on the target system. If the TripleSec key is negotiated using ephemeral ECC or DH it's less critical, but with small tweak values the payload is still vulnerable.

commented

@SparkDustJoe Gotcha, Completely different use case for me, I was focused on local encryption completely under the clients control not transport.

It is possible with the parameter string output from Argon2 to have the scrambling variables captured for the decryptor (referencing #51 ). Reading back through this thread, the use case of using Triplesec as a transport security layer instead of a storage security layer seems, admittedly, a bit moot (out-of-band), but the notion of opening Triplesec encrypted files on mobile is still prescient.