C Encryption Cryptography – Safest Way to Tell if Decryption was Successful

ccryptographyencryptionssl

I'm making a C program that uses GTK3 (best documentation ever) and OpenSSL (worst documentation ever) to simply encrypt/decrypt a file using a password. The encryption and decryption functions are both working, however if I enter the wrong password in the decryption phase, the file becomes corrupt (obviously). So I need a way for the decryptor to detect if it's job was successful. Here are my solutions so far:

  • AFTER encrypting, prepend a check-sum (sha1/sha256) of the original data to the file. So the decryptor can validate the original checksum and decrypted data's checksum.

  • BEFORE encrypting, prepend a constant value (ie "CHECK STRING") to the file, and if the decryptor see's that the constant value was successfully decrypted, it can assume the entire file was too.

Can the unencrypted checksum be cross-analysed with the encrypted data in order to speed a brute force?

Could the encrypted constant value, who's unencrypted value is known by the attacker, reveal to the attacker a limited number of passwords that could encrypt the constant in that manner?

I hope this makes sense, I hate being esoteric.

Best Answer

I recommend using authenticated encryption. Its main purpose is that an attacker manipulating the ciphertext can't change the message without getting detected. But it will also reject incorrect keys.

You can either:

  • Use an existing authenticated encryption algorithm, like AES-GCM, AES-CCM or XSalsa20Poly1305.
  • Build one from encryption and a MAC using the encrypt-then-MAC construction.

    A MAC is similar to a hash, but keyed. You can only compute its output if you know the key.

Other constructions, like the ones you mention in the question are not secure when combined with common encryption algorithms like AES in CBC mode. The best known weakness is the padding oracle attack against unauthenticated CBC mode, but similar attacks apply to many such ad-hoc constructions.

If you want you can store a value derived from the master key (e.g. using HKDF) in the header. That can help distinguish between an incorrect key and a corrupted/truncated file.

Related Topic