Thank you to Allen Mann for discovering the following significant security vulnerability in RNCryptor.
RNCryptor computes the HMAC over the ciphertext only. It does not compute an HMAC over the header, particularly the IV. This allows an attacker to modify the IV and thus manipulate the first block (16-bytes) of decrypted plaintext. This is a major issue, and is exactly the kind of problem that RNCryptor is designed to avoid.
I will be modifying RNCryptor shortly to fix this. This will rev the file version to 2. I will provide a backward-compatibly option to read v1 files (default off). I strongly recommend that developers move to the v2 format.
I will try to get this out as quickly as I can, hopefully this week.
There is a valuable lesson here. I know this vulnerability in AES. I have given talks about it. I’ve demonstrated it with exploit code. I wrote RNCryptor explicitly to avoid this vulnerability. Yet I screwed up the implementation and so RNCryptor is currently vulnerable to it.
I didn’t find this problem myself. I’m in the process of designing a different encrypted data format for a client, and I correctly compute the HMAC in that format, and I still didn’t clue-in that I’d done it wrong in RNCryptor.
How was it found? By someone who didn’t just take my word for it. He looked at the implementation, saw the error, wrote his own exploit to prove it to himself, and informed me.
OpenSSL has been written by people very concerned with security. It’s been riddled with security bugs over the years. (I wrote RNCryptor directly in response to the serious problems in its AES format.) PGP, SSH, Kerberos, security protocols, formats, and implementations, even if built by smart people who are aware of the issues, they often have vulnerabilities. Some subtle, some bone-headed (like this one).
So what should you take away from this?
Trust security systems in proportion to how much public scrutiny they receive. The more closed a system, the more it relies on proprietary and secret techniques, the less you should trust it. Open source systems have many errors. Don’t imagine that proprietary systems have fewer; they just aren’t found and fixed.
A security system is only as good as its implementation. The RNCryptor v1 format uses HMAC, which is good, but the implementation is slightly wrong and that creates a vulnerability. Just because your system uses AES and AES is strong doesn’t mean that your system is secure.
You need to educate yourself on the basics of how cryptographic systems work. As a developer you need to be able to evaluate whether the cryptography framework you’re using is secure, and even more critically you need to be able to evaluate whether you’re using it securely. Common Cryptor’s HMAC functions are fine, but if I pass the wrong data, the system is still insecure.
Assume that any security framework you have will need to be upgraded in the future, possibly in incompatible ways, to address vulnerabilities. Design your project to make upgrading as simple as possible.