pycrypto / pycrypto

The Python Cryptography Toolkit
https://www.pycrypto.org/
Other
2.45k stars 636 forks source link

pycrypto AES cipher issue in py3.5 #183

Open alekspir opened 8 years ago

alekspir commented 8 years ago

Note, this is a re-post of my question at stackoverflow (http://stackoverflow.com/questions/34956921/python-crypto-aes-cipher-decode-type).

I'm having a little problem using AES_CBC cipher decode function. When I assume (via a file open(x,'wb')) its return is bytes, python complains about getting a string in the write() function. When I assume (open(x,'w')) its return is string, python complains about getting bytes in the write() function. Can anyone please explain the issue here? (Python 3.5.1 for reference on Win7)

def decrypt(in_file, out_file, key,iv):
bs = AES.block_size
cipher = AES.new(key,AES.MODE_CBC,iv)
next_chunk = ''
finished = False
while not finished:
    try:
        chunk, next_chunk = next_chunk, cipher.decrypt(in_file.read(bs))
    except ValueError:
        finished = True
    out_file.write(chunk)

with open(in_filename, 'rb') as in_file, open(out_filename, 'wb') as out_file:
    decrypt(in_file, out_file, key, iv)

Results in

TypeError: a bytes-like object is required, not 'str'

Changing the file opening statement to

with open(in_filename, 'rb') as in_file, open(out_filename, 'w') as out_file:
decrypt(in_file, out_file, key, iv)

Results in

TypeError: write() argument must be str, not bytes

The best I could do is cast the chunk to string with str(chunk), but then my output file is a bunch of byte strings like

b", 'Shutdown', 'R"b"eboot', 'SetPowe"b"rSave'} (string "

I did get the code to run using py2.7: I created a new environment using conda create -n python2 python=2.7 anaconda , set VS2015 to use that, and then the code worked fine with just a 'wb' file and out_file.write(chunk)- so I'm thinking this is 3.5 specific.

varjoranta commented 7 years ago

The same issue with RSA encrypt. The problem is in python3 bytes and strings change.

Example to fix, check the following line: https://github.com/dlitz/pycrypto/blob/7acba5f3a6ff10f1424c309d0d34d2b713233019/lib/Crypto/Cipher/PKCS1_OAEP.py#L150

This should be:

db = lHash + ps + bchr(0x01) + message.encode('ISO-8859-1')