4 ms·
The third demo screenshot [1], which contains a toy implementation of AES in CBC mode, is a great example of why cryptography is hard to get right. Implementati
by fiberoptick 8y ago
The third demo screenshot [1], which contains a toy implementation of AES in CBC mode, is a great example of why cryptography is hard to get right. Implementation is best left to cryptographers.
AES-CBC requires a random IV to be used as a nonce on a per-message basis, otherwise the entire scheme breaks. The toy example given on this website uses the deprecated Node.js createCipher [2] API which does not take such an IV. In fact, the docs and runtime even warn that using CBC mode with the createCipher API is dangerous!
As the code is currently written, an attacker observing multiple encrypted messages under the same key could probably decrypt all messages!
[1] https://projects.lukehaas.me/runjs/images/runjs3.png https://projects.lukehaas.me/runjs/images/runjs3.png
[2] https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password_options https://nodejs.org/api/crypto.html#crypto_crypto_createciphe...
- rubyn00bie 8y agoI totally understand why you're saying what you are, you want folks to be safe... but I think this approach from cyptographers hurts the rest of us, in that most of us will at some point say, as a result of comments like this, "I'm not a cryptographer, I cannot do this correctly... so fuck trying." I think critiquing this crypto used would be more relevant if he was implementing his own and not using using an outdated library. Instead of linking to proof about how right you are, since you obviously are, perhaps next time you could link to resources for us plebs to stay up-to-date. How do you keep tabs on "all the things" like this? /shrug just my two cents.
- barrkel 8y agoI think explaining why the crypto usage is wrong is useful, where a straight-up admonishment that someone is doing it wrong isn't. The principle here is explained, at least partially: if you don't use a random IV for every message, you're not secure. So if the API you're using doesn't let you specify the IV, or doesn't default to a random IV that leaves you with undecipherable blocks if you don't fetch its assigned value, you know it's wrong. It's good info.
- Waterluvian 8y agoCryptography is like civil engineering or surgery. If you're going to do it in production, you need to do it right. I think it's akin to a family physician saying, "this is best left to the surgeons." Don't be fooled that just because you can write code, you can do crypto. But also, you can learn and you can also completely mess around in a safe, non-production environment. Maybe my analogy is a bit weak.
- nicoburns 8y agoI think your analogy is pretty spot on. Cryptography is an additional skill on top of general programming, and it's a difficult one to master. And if you haven't mastered it, then you shouldn't be trying to do it in important situations (assuming there is an alternative).
- andy_ppp 8y agoI disagree, cryptography is like any programming; make sure it’s correct with tests, peer review and validation and check the warnings (this warning should be an error). The fact that a small example gets this badly wrong and the API allows this is probably down to the ecosystem, not down to only cryptographers being “allowed” to used crypto. The surgery idea is wrong; surgery is the implementation of the encryption which no one is advocating - this is more like a pharmacist giving you the wrong pills and you not reading the instructions/warnings before taking them.
- tlrobinson 8y ago> most of us will at some point say, as a result of comments like this, "I'm not a cryptographer, I cannot do this correctly... so fuck trying." I'd argue that in most cases not using crypto is better than using subtly broken crypto. At least users aren't deluded into thinking it's secure, and can take that into consideration when using (or not using) the system.
- zapzupnz 8y ago> "I'm not a cryptographer, I cannot do this correctly... so fuck trying." Whoever says this, whoever doesn't put in the hard yards to actually get good at cryptography, who is content with hugely flawed crypto — well, they shouldn't be in crypto in the first place. And those unable to take constructive criticism, I don't know if they should be in real life.
- eknkc 8y agoThe `createCipher` API derives an IV from the passphrase so basically it uses a static IV for each passphrase. If you used it and need to switch to the new API but be able to decrypt old stuff, here's some code to get the IV that the deprecated API actually derives, so you can use it with the new API: https://gist.github.com/bnoordhuis/2de2766d3d3a47ebe41aaaec7e8b14df https://gist.github.com/bnoordhuis/2de2766d3d3a47ebe41aaaec7...
- ehsankia 8y agoTangentially relevant but here's a great example of important the AES mode can be: https://vikingvpn.com/blogs/security/visualizing-weak-encryption-experiments-with-aes https://vikingvpn.com/blogs/security/visualizing-weak-encryp...
- deleted 8y ago[deleted]
- skrebbel 8y ago> Implementation is best left to cryptographers. You suggest we hire a cryptographer every time we need something secured? I mean, come on, this is ridiculous. The code quoted does not implement encryption, it invokes encryption. The AES algorithm being invoked, I expect, was written by proper cryptographers. The reason this code is insecure is that the API is a piece of shit. Most standard crypto modules have calls of the form encrypt(algorithmName, arg, arg) Depending on the algorithm chosen totally different parameters need to be passed or else. Or else what? Or else the function works perfectly well, produces an encrypted byte array, but with totally broken security. The programmer will be none the wiser except if they were lucky enough to post the code somewhere on HN and someone writes a condescending comment. This is shit design and we can blame the cryptographers. It doesn't have to be this way. Some languages and libraries get it right, here and there. Eg PHP doesn't just expose a way to call bcrypt, but also has two functions password_hash and password_hash_verify. These implement all the best practices, with seeds, the right algorithm parameters, keeping the ability to rehash in the future, etc. We need similar APIs for symmetric and asymmetric encryption, for common use cases, or this madness is simply going to continue. Cryptographers, please get your act together. Job safety is nice, but a secure internet is nicer. Please make it easy for morons like me to use crypto right. I mean, I don't even know what the different considerations are so I can't design these functions right, so please consider the spirit of the following proposal and not the details. What about a function like encrypt_symmetric_for_single_user(payload, userid, key) which takes care of picking the right algorithm, doing the right dance with keys and nonces and whatnot? Or maybe functions need to include naming like encrypt_for_sending_once and encrypt_for_storing_long? My understanding is that you want different crypto in such cases, right? I'm sure better cryptographers than me can immediately see what I'm doing wrong here, but you catch the gist right? Why can't this be made easier? Why do we at the same time, collectively, shame everyone who gets security wrong and make it so unnecessarily hard for people to get right?
- deleted 8y ago[deleted]
- snops 8y agoNaCL: https://nacl.cr.yp.to https://nacl.cr.yp.to Is a crypto library designed to do exactly this, have a sensible API that does not expose any internal details for misuse, and generally gives you only one way to do things based on best practice algorithms. It's got some big names behind it, and has probably quite mature since it's been going for several years. There is also a popular fork, libsodium: https://libsodium.gitbook.io/doc/ https://libsodium.gitbook.io/doc/, which I think is more portable.