1

I'm using python to encrypt and decrypt files. When file encrypted, then try to decrypt like this:

from Crypto.Cipher import AES
from Crypto import Random
def decrypt(in_file, out_file, pwd, key_len=32):
    bs = AES.block_size
    salt = in_file.read(bs)[len('Salted__'):]
    key, iv = derive_keyiv(pwd, salt, key_len, bs)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    next_chunk = ''
    finished = False
    try:
        while not finished:
            chunk, next_chunk = next_chunk, cipher.decrypt(in_file.read(1024*bs))
            if len(next_chunk) == 0:
                padding_len = ord(chunk[-1])
                chunk = chunk[:-padding_len]
                finished = True
            out_file.write(chunk)
        return True, None
    except Exception as e:
        return False, e

But if the password input error, the decrypt still decrypt in_file and write to out_file and no exception throw.

How to check the password error during decrypt?

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
coanor
  • 3,746
  • 4
  • 50
  • 67

1 Answers1

3

AES by itself cannot check if the key is "correct". It is simply a pure function that transforms some bytes to some other bytes.

To achieve what you want, you need to implement it yourself. One way to do is to add a fixed header (like 16 bytes of zero) to the plaintext before encryption. Upon decryption, check and discard the said header if it matches or raise an error if the header mismatches.

A side note: you are doing encryption without any authentication, which is probably insecure.

Edit

First of all, you should add authentication. Encryption without authentication easily leads to many security flaws, many not obvious to the untrained. Especially since you are using AES in CBC mode, you may open yourself to padding oracle attacks without authentication.

When you do authenticated encryption the right way (encrypt-then-mac), you will get an authentication error if the user input the wrong password. If you want to further distinguish a wrong password from tampered data, you have to devise your own method, like prepending a ciphertext of magic number.

Siyuan Ren
  • 7,573
  • 6
  • 47
  • 61
  • 1
    Why add additional block of zeros if one could actually verify the padding? You said it. **Authentication** is the way to go with encrypt-then-MAC. – Artjom B. Aug 19 '15 at 09:58
  • @ArtjomB. Authentication cannot distinguish between tampered file from incorrect password. – Siyuan Ren Aug 19 '15 at 09:59
  • @ArtjomB. On second thought, verifying the padding after verifying the mac is indeed a way. But if the mode is GCM, for example, authentication cannot distinguish incorrect password and tampered data. – Siyuan Ren Aug 19 '15 at 09:59
  • Yes, authentication is slightly different from just detecting a typo in a password, but I would argue that if the file was tampered with, you don't want to try to open it. – Artjom B. Aug 19 '15 at 10:02
  • *"like prepend a ciphertext of magic number."* The length of that number determines the probability of correctly detecting a wrong password. If it is 4 bytes long, then you have a probability of $2^{-4*8}$ of not detecting a wrong password which is already quite low. – Artjom B. Aug 19 '15 at 12:26
  • http://stackoverflow.com/a/20457519/342348 added code to check the password of decryption. – coanor Sep 06 '15 at 06:26