-
Notifications
You must be signed in to change notification settings - Fork 272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Recommending CTR is dangerous, if the same key is used twice #113
Comments
Whats your opinion? What settings should i use with this lib |
Generate new random 16-byte counter for every message and then send it as plaintext alongside encrypted message. |
The IV is necessary to decrypt the content in the future, so picking a random IV would be unwise (also, it is hard in many environments to generate a random number portably, so I would recommend against any library not equipped to do so, from generating a random number). Often the source of the IV comes from either a random source, or from the use of a session (or ephemeral) key mixed with a known public key for another’s private key, and the public key of this session key is prepended to the cipher text. As an aside, due to the dangers of choosing a “random” number (which is difficult and something easy to hijack), a method similar to RFC-6979 might be preferably, where a hash (HMAC, preferably) of the key and content is used to create a deterministic IV; this means the same plaintext produces the same cipher text and that different plaintexts get different IV. However, do NOT do this if multiple messages will match and you do not want to leak the pattern. You also can’t do this if it is planned as a streaming cipher (one of the advantages of CTR node). This is just an example technique, for very specific cases. The AES block cipher is a cryptographic primitive, so it’s very important to understand and use it properly, based on its application. It’s a powerful tool, and with great power, yadda, yadda, yadda. :) Does that make sense? |
Unique secret keysIf you can use different key/passwords for each encryption, you can you CTR, and just count up from 1. (And stop reading the rest of this post. : ) Reusing secret keysIf you have to use the same secret key/password for multiple/all encryptions, you must pay more heed to the IV. Keep reading: Synthetic IVsHashing the plaintext to create an IV (as @ricmoo is explaining above) is a often good solution. (The concept is often called SIV, Synthetic IV, and used in AES-SIV, AES-GCM-SIV.) The downside of SIV is that two equal massages will be encrypted identically. So an eavesdropper, can pick up that you are sending the same message over and over, and when you do so. If this is not a problem (or if it is a benefit), feel free to go for the SIV approach. And you'll be free to choose AES-CTR, (or CBC, or another.) Careful designIf none of these apply, you have to carefully design a IV regime that avoids having the same IV for the same secret key/password. Abd in this case, I would be very careful about using AES-CTR. As it fails catastrophically if you get a collision. The security of AES-CBC is weakened in this situation, but doesn't completely collapse. MalleableIf I catch an encrypted message, I may not be able to decrypt it. But nothing is stopping me from changing a bit or two in the encrypted message, before passing it on. And if I know something about the contant, I can actually "edit" the encrypted messages to a certain extent, (e.g. turning If this is not an issue for you case, don't worry about it. If it is a worry, you need to use HMAC (as mentioned above), or another AES mode that includes an HMAC, such as AES-GCM. |
How catastrophically is catastrophically, by the way? For example, of 1000 encrypted messages I've got 2 that share same key and IV; and attacker intercepted all 1000 messages, but doesn't know about IV collissions beforehand - how bad is this situation for me? |
It's hard to find proper sources for this. Most just say it "fails catastrophically". From what I understand, The attacker can manage to decode the two messages with the colliding IVs, but not retrieve the secret key, and therefor not decode the other messages. One source I've found is this Stack Exchange post: https://crypto.stackexchange.com/questions/2991/why-must-iv-key-pairs-not-be-reused-in-ctr-mode Which links to another answer: https://crypto.stackexchange.com/questions/2249/how-does-one-attack-a-two-time-pad-i-e-one-time-pad-with-key-reuse I presume an attack in your example could be XORing all the encrypted messages against each other. If the plain text are mostly plain text, any colliding IVs would yield an XOR-result with very few of the bit 7 ever being set. And then you start digging. A bit of work involved, though. :) |
I agree that the library shouldn't recommend CTR. const aesjs = require("aes-js")
const newCtr = () => new aesjs.ModeOfOperation.ctr(aesjs.utils.utf8.toBytes("password12345678"))
// The known ciphertext-plaintext pair:
const cipher = aesjs.utils.utf8.toBytes("hello")
const plain = newCtr().encrypt(aesjs.utils.utf8.toBytes("hello"))
// Decode a ciphertext:
const target = newCtr().encrypt(aesjs.utils.utf8.toBytes("world"))
console.log(aesjs.utils.utf8.fromBytes(target.map((t, i) => t ^ plain[i] ^ cipher[i]))) // "world" Even if the attacker does not know a pair of plaintext and ciphertext, the plaintext for a ciphertext may be deduced from the length of the ciphertext. 1
This case is somewhat more difficult, but still, for every plaintext-ciphertext pair you found, you can decrypt 0.2% of the messages. On the other hand, CBC has no such problem. |
AES-CTR fails catastrophically when one reuses the same key, and the same IV/counter.
Could you please update the README to warn people to never, ever, ever reuse the IV when using AES-CTR?
When using CTR, the developer has to create a method of ensuring that a new IV/counter is used every time, if the is a chance that the key can be used.
Therefore the default should probably not start counting at 1, but at a random number, unless the developer explicitly specify a counter.
The text was updated successfully, but these errors were encountered: