encryptionencryption-symmetric

How to check the validity of a symmetric key?


User 1 sends two fields:

these fields are passed to encrypt function

encrypted = encrypt(plain_text, password)

the encrypted value is stored in the database


Now User 2 wants to see this plain_text field, he sends one field to the server to request it:

Now the server wants to check to see if the password sent by User 1 is the same as the password sent by User 2 but at the same time he did not store the password sent by User 1, how can the server check that the password is correct before sending the decrypted text.

The motive is that the server is not wanted to:

  1. send wrong decrypted text
  2. store the plain_text in the database
  3. store the correct password in the database

What is the simplest way to achieve this?


Solution

  • The standard way to do this is to use an authenticated mode, like GCM or CBC+HMAC. An authenticated mode will fail to decrypt if the key is incorrect rather than returning a corrupted plaintext.

    Authenticated modes generally do not tell you that the decryption has failed until the end, which can be problematic for very large payloads. In those cases you encrypt and store a static (or computable) piece of data with the same key (or a key derived from the same key) using the same authenticated mode. You can use that to pre-flight the key before decrypting the larger payload.

    But the short answer is: use an authenticated mode, ideally GCM, and you get this and more for free.

    Without changing your existing mode, you can achieve this by prepending the hash of the payload to the payload before encrypting. After decrypting, split the hash and payload, hash the payload, and ensure that it matches the decrypted hash.