How Not to Encrypt a File — Courtesy of Microsoft
A client recently sent me a crypto spec which involved some, how do I say, suboptimal use of crypto primitives. They’re .Net users so I decided to search for a nice msdn crypto reference to set them straight. Instead I found the likely culprit behind their confusion.
The article in question is this one: How to encrypt and decrypt a file by using Visual C# (has since been taken down, victory!). If you’re in the mood for some forehead slapping I recommend reading it. Here are some of the funny-if-they-weren’t-sad pieces of advice I found:
Use of DES for encryption
And no, I don’t mean 3DES, just plain DES. The one that can be brute forced in a single digit number of days by a modern computer. Keep in mind the intended audience for this article isn’t cryptographers who know better, it’s programmers looking for a tutorial. It’s a good thing the caesar shift isn’t available in their library or it would probably have ended up in this tutorial.
Suggestion to use the encryption key as the IV
This was the first in a series of data points which suggest that the author has no idea what an IV is or how it’s supposed to be used. This suggestion actually comes up more than once in the article, here are the offending passages:
You can prompt the user for a password. Then, use the password as the key and the IV.
Note that there is no mention of a using a key derivation function, just a suggestion to use the password directly.
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
This passage is probably even worse in that it’s actual code that unsuspecting readers could potentially copy and paste.
Advice against using the library’s key and IV generation functionality
Using a single password as the key and the IV is a pretty terrible suggestion, but luckily the library has a method for generating a key and IV for you so you don’t mess it up. Unfortunately the author explicitly advices against it for a nonsensical reason.
If you do not provide a key, the provider randomly generates one. This successfully encrypts the file, but there is no way to decrypt the file. Note that you must also provide the initialization vector (IV). This value is used as part of the encryption. Like the key, the IV is randomly generated if you do not provide the value. Because the values must be the same for the encryption and the decryption, you must not permit random generation of these values.
Emphasis mine. So apparently if you use the key and IV generation functionality of the library there is no way to perform decryption. I have to wonder why the author thinks the library authors chose to include this irreversible data destruction functionality. The author even takes it a step further and makes the blanket statement that keys and IVs shouldn’t be randomly generated at all.
IV not included with the ciphertext
This one is subtle because you have to either really follow the logic or try running the code yourself. This probably explains why the author treats the IV as if it’s another secret key.
References get the IV wrong also
It may seem like I’m really raking this guy over the coals for his misunderstanding of what an IV is or how it’s used; after all this isn’t an article about block cipher modes or cryptographic keys, and it even links to a reference specifically about cryptographic keys. Surely that clears everything up, right? Right?? This is literally the second sentence in that article:
Symmetric algorithms require the creation of a key and an initialization vector (IV) that must be kept secret from anyone who should not decrypt your data
But at least that article uses triple DES in their example.