As a result of an interesting (if you're nerdy
) discussion going on in this thread
, I started experimenting with definition files, specifically how the user-supplied encryption password is stored.PROBLEM
Although Reflect encrypts the user-supplied encryption password before storing it in the definition file, a given password always encrypts to the same ciphertext
. I understand that users are expected to safeguard their definition files, but that doesn't mean this can't be improved.THREATS
A consistent relationship between a given plaintext and the generated ciphertext creates two possible threats:
- An attacker could compute a rainbow table, a one-time effort that could then be used to look up plaintext passwords from the ciphertext version stored in definition files. Any plaintext passwords whose length and composition were within the "scope" of the rainbow table would be vulnerable to compromise.
- An attacker could mount a chosen plaintext attack in an attempt to derive the key/mechanism that Reflect uses to encrypt/decrypt these stored passwords. ALL passwords encrypted in definition files would be vulnerable to compromise, regardless of the length or composition of the original plaintext.OPPORTUNITY
I believe my proposed solution below completely eliminates the rainbow table threat and significantly reduces the key derivation threat, while maintaining compatibility with existing definition files and seemingly requiring minimal effort to implement.
I propose that Macrium expand their definition file XML by giving the existing <password> tag a new "Type" value, perhaps named "EncryptwithSalt". Whenever the user supplied a new encryption password, Reflect would append a randomly generated, but fixed-length
salt to it, and generate the ciphertext to be stored in the definition file from that combined string. When the password was needed, Reflect would decrypt that ciphertext and then remove the fixed-length number of characters from the end of the resulting plaintext to recover the user-supplied password. The purpose of the new "Type" value is to maintain backward compatibility with existing definition files, i.e. for any definition file whose <password> tag has its Type set to the current "Encrypt", Reflect would not perform this truncation after decrypting the stored password.
The end result is that a given user-supplied password will encrypt to different ciphertexts in different definition files, thereby thwarting rainbow table-style attacks, and the combination of a) this salt resulting in variable ciphertext for a given password and b) never actually writing the salt anywhere, makes it more difficult to derive Reflect's encryption key through chosen plaintext attacks. In fact for additional security, it may be worth Reflect steganographically hiding the salt when it is computed, using techniques already employed for its encryption key.DRAWBACK
The only drawback I can see is that definition files that use this new <password> Type value would not be usable by older versions of Reflect, but I don't consider that a significant issue.