I already have a working program, but the only thing that doesn\'t work is the decrypt_file()
function I have. I can still copy the encrypted text from the file
I took a closer look at your code, and saw that there were several problems with it. First one is that the crypto functions with with bytes, not text. So it's better to just keep the data as a byte string. This is done simply by putting a 'b' character in the mode. This way you can get rid of all the encoding and bytes conversion you were trying to do.
I rewrote the whole code also using newer Python idioms. Here it is.
#!/usr/bin/python3
from Crypto import Random
from Crypto.Cipher import AES
def pad(s):
return s + b"\0" * (AES.block_size - len(s) % AES.block_size)
def encrypt(message, key, key_size=256):
message = pad(message)
iv = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
return iv + cipher.encrypt(message)
def decrypt(ciphertext, key):
iv = ciphertext[:AES.block_size]
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext[AES.block_size:])
return plaintext.rstrip(b"\0")
def encrypt_file(file_name, key):
with open(file_name, 'rb') as fo:
plaintext = fo.read()
enc = encrypt(plaintext, key)
with open(file_name + ".enc", 'wb') as fo:
fo.write(enc)
def decrypt_file(file_name, key):
with open(file_name, 'rb') as fo:
ciphertext = fo.read()
dec = decrypt(ciphertext, key)
with open(file_name[:-4], 'wb') as fo:
fo.write(dec)
key = b'\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\x9e[EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\x18'
encrypt_file('to_enc.txt', key)
#decrypt_file('to_enc.txt.enc', key)
In Python 3 (which you are clearly using) the default mode for files you open is text, not binary. When you read from the file, you get strings rather than byte arrays. That does not go along with encryption.
In your code, you should replace:
open(file_name, 'r')
with:
open(file_name, 'rb')
The same for when you open the file for writing. At that point, you can get rid of all the various occurrences where you convert from string to binary and vice versa.
For instance, this can go away:
plaintext = plaintext.encode('utf-8')