My department at work is required by the powers that be to use an encryption library written by another department, the problem being that the encryption library has hard-coded its AES counter mode initialization vector (all-zeros). (Basically, the other department took the Bouncycastle library and wrapped their own broken code around it.) We have documented the problems with this code for the powers that be, so now unless management decides to act we're stuck using a broken encryption library.
I am wondering if we could fake a proper initialization vector by prepending a unique IV to the plaintext and then truncating the first sixteen bytes of plaintext after decryption, e.g.
ciphertext = encrypt(++sixteenByteCounter + plaintext)
plaintext = decrypt(ciphertext).subArray(16, ciphertext.length)
This seems fine to me, but I'm hardly a cryptography expert
Noooooo....
In CTR mode you are encrypting a sequence of numbers (1,2,3...) and then XORing your message against that.
It's notoriously easy to crack encryption that XORs values against a re-used sequence. So to avoid this in CTR mode you start at a random offset each time (you don't start at 1, but at 75437454896785, for example). That's what the "IV" is in CTR mode. It's not like an IV in chaining. It's a numeric offset to where you start counting.
See https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29 - the IV is the "nonce" (the higher bits in the counter).
What you suggest seems to be based on CBC mode or similar where the IV is used to mangle the next block, which is in turn used to mangle the next block and so on. But that's completely unrelated to the way IV is used in CTR mode.
Your fix would not change the starting point of the numbers used, and your messages would be hopelessly insecure. Please don't do this.
Also, there's a crypto equivalent to stackoverflow where you should really ask this kind of thing. https://crypto.stackexchange.com/
BUT WAIT. Now I think about this... I don't know the API in question. It could be that the IV is simply not used (maybe the IV in the API is only used for the kind of chaining that is done in CBC). How wide is the counter? Could it be that the API expects you to start the counter with a random offset? I guess not, but you really need to read the docs / code to be sure (I know I was bitten on this issue with PyCrypto).
But anyway, either way, your fix is certainly not a fix (unfortunately).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With