1

I'm using the Haskell Codec.Crypto.SimpleAES package to create a crude password manager. The password manager seems secure but it's unable to warn the user when the decryption key is invalid. If a user supplies a bad decryption key, the program just sends back garbage instead of an "Invalid Decryption Key" error.

I want to give the user an error when a bad decryption key is supplied. The easiest way I can think of doing this is to hash the decryption key and save it in a local file when the password manager is initialized. From then on, whenever a user requests a password, the program would then check the supplied decryption key against the hashed value before invoking the decryption algorithm. If the key didn't match the hash, the program would send back an error, but if the key did match, the program would decrypt the requested password and send it back to the user.

If the password manager stores a hashed instance of the decryption key in a local file, would that significantly lower security?

Shawn Eary
  • 113
  • 5
  • 5
    If this significantly impacts the security of the solution depends on how good the password is protected. A simple hash will not be sufficient. Therefore possible duplicate of [How to securely hash passwords?](https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords) – Steffen Ullrich Jul 27 '19 at 13:12
  • That definitely helps, but do most decryption libraries return an error or "garbage" when the key is invalid? – Shawn Eary Jul 27 '19 at 13:45
  • What is the strength of your decryption key? – Amey Jul 27 '19 at 13:47
  • 2
    *"... most decryption libraries return an error or "garbage" when the key is invalid?"* - encryption does not necessarily include authenticity. Either you add a MAC/HMAC for authenticity or you use encryption methods which include this - see [Authenticated encryption](https://en.wikipedia.org/wiki/Authenticated_encryption). – Steffen Ullrich Jul 27 '19 at 13:50
  • @Amey - There's a story to that but the short answer is 256 bits. The longer answer is that *some* of the 32 decryption key bytes are stored in the user's head and the rest are stored in a local file in plain text: https://stackoverflow.com/questions/56824810/how-do-i-safely-read-an-encryption-key-via-a-haskell-command-line-program – Shawn Eary Jul 27 '19 at 14:02
  • 1
    Why don't you add some simple plain text to the end of your encrypted contents? If you can recover your plain text then the key was correct. I wouldn't encrypt the plain text by itself, and I don't guarantee this suggestion doesn't accidentally open its own security holes. Which is why the age old advice of "don't roll your own crypto" exists – Conor Mancone Jul 27 '19 at 16:12

1 Answers1

2

What you are looking for is called a Key Check Value (KCV).

You create a KCV by encrypting a block of zero bytes in ECB mode (the same number of null bytes as your cipher’s block size), then saving the first three bytes of output as a six character hexadecimal string, such as A1B2C3.

In the future you can test a key by executing the same KCV algorithm; if the bytes are uncorrupted, it will yield the same KCV. This method is often used as a verification for high security keys that are delivered on paper by couriers.

The output is deliberately limited to not contain enough data to reveal significant information about the key. And by not using a hash, it doesn’t risk exposure due to an unknown or unforeseen weakness in the hash algorithm.

John Deters
  • 33,650
  • 3
  • 57
  • 110