I'm making a small python program to encrypt an arbitrary text file.

Currently I have a file to store passwords (hashed values), so nothing stored in plaintext. The user enters the command line arguments of a flag '-e' or '-d' to encrypt or decrypt, and a filename and a password. The password to encrypt is different to the password to decrypt, one cannot be used for the other.

The encryption works although I'm not 100% sure I'm doing it correctly. I take the file and read through it line by line, appending each line to a list. Then making a random 128 bit IV using the hashed password the user entered as a key to encrypt each line. Then I write these lines to a new file and save the file.

I'm not sure I should be using the hashed password the user entered as the key to encrypt, because I'm saving the hashed value of the password the user entered in a password file to check against user input! (if that makes sense).

Anyway my main problem is decryption, because the file was encrypted with PASSWORD_ENCRYPT, and the user wants to decrypt with PASSWORD_DECRYPT, the two are not the same. So I don't have the key to decrypt the file?

Here's some code of my encryption.

backend = default_backend()
key = hashed_password
iv = os.urandom(16)
cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=backend)  
encryptor = cipher.encryptor()
lines_of_ct = [iv]
for each_line in list_of_incoming_lines:      
    b = each_line.encode('utf-8')           

    with open(file + ".enc", "w") as enc:
        for each_line in lines_of_ct:
            print(each_line, file=enc)

My question is, how can I decrypt the file with the user entering a different password for read access (decryption). Is there a way to safely append the original encryption password/key to the file so I can retrieve it and use it? Like I have done with the IV, I attached that to the star


1 Answer 1


To make the encrypt and decrypt passwords different, whoever has access to the encryption password would also need to know the key derived from the decrypt password, and the encrypt password simply unlocks that key. Then you have something like this:

Enc password is entered
Enc password is derived to key $K_E$
$K_E$ is used to decrypt the stored decrypt key $K_D$
A random key $K_R$ is used to encrypt the data
$K_R$ is encrypted with $K_D$ and appended to the message with the IV

Upon decrypt, the correct password will be derived to $K_D$ and used to unlock $K_R$, which can then decrypt the message.

In regards to the rest of your system, reading line by line is a very bad idea. In this case you are not encrypting the line breaks, and someone looking at the encrypted data will know the approximate structure of the message. You should read the file as a stream of bytes from end to end and encrypt all of them. The ciphertext should also not use any kind of encoding, as that could cause a problem during decryption. If you need the ciphertext to be copyable as text, like into an email or text message, it should be encoded to Base64.

Also simply hashing a password for use as a key is wrong, you need a key derivation function such as PBKDF2. There are MANY questions regarding this here, I would suggest reading a few of the highest voted questions and answers.

  • $\begingroup$ But how do I store the derived key. I know the decrypt password but the derived key will contain random salt, so every time the program is run, the derived decrypt key will be different ? $\endgroup$
    – user249440
    Feb 23, 2016 at 15:10
  • 1
    $\begingroup$ @user249440 you DONT use a random salt everytime you derive the key, only when you change the key. The salt would be read from storage so that the derived key will always be the same, otherwise nobody would be able to decrypt the files, ever. $\endgroup$ Feb 23, 2016 at 21:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.