2

Trying to encrypt/decrypt text with aes encryption with python 3, using pycryptodome 3.4.2

Of course, I found this method on the Internet and tried to change it for my needs and all that I'm getting are the errors.

Here's the code:

def aes():
    #aes
    print('1.Шифруем')
    print('2.Дешифруем')
    c = input('Ваш выбор:')
    if int(c) == 1:
        #shifr
        os.system('clear')
        print('Шифруем значит')
        print('Введите текст, который хотите зашифровать')
        text = input()
        with open('Aes/plaintext.txt', 'wb') as f:
            f.write(text.encode('utf-8'))
        BLOCK_SIZE = 16
        PADDING = '{'
        pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
        EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
        secret = os.urandom(BLOCK_SIZE)
        with open('Aes/secret.bin', 'wb') as f:
            f.write(secret)
        cipher = AES.new(secret, AES.MODE_CFB)
        with open('Aes/plaintext.txt', 'rb') as f:
            text = f.read()
        encoded = EncodeAES(cipher, text)
        with open('Aes/ciphertext.bin', 'wb') as f:
            f.write(encoded)
        print (encoded)
    if int(c) == 2:
        os.system('clear')
        print('Дешифруем значит')
        PADDING = '{'
        with open('Aes/ciphertext.bin', 'rb') as f:
            encoded = f.read()
        with open('Aes/secret.bin', 'rb') as keyfile:
            secret = keyfile.read()
        DecodeAES = lambda c, e:    c.decrypt(base64.b64decode(e)).rstrip(PADDING)
        cipher = AES.new(secret, AES.MODE_CFB)
        decoded = DecodeAES(cipher, encoded)
        with open('Aes/plaintext.txt', 'w') as f:
            f.write(str(decoded))
        print(decoded)    

But when I'm trying to decrypt some text, I get this error:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3/dist-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 699, in runfile
execfile(filename, namespace)
File "/usr/lib/python3/dist-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 88, in execfile
exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)
File "/home/tukanoid/Desktop/Enc_dec2/Enc_dec.py", line 475, in <module>
aes()
File "/home/tukanoid/Desktop/Enc_dec2/Enc_dec.py", line 178, in aes
encoded = EncodeAES(cipher, text)
File "/home/tukanoid/Desktop/Enc_dec2/Enc_dec.py", line 166, in <lambda>
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
File "/home/tukanoid/Desktop/Enc_dec2/Enc_dec.py", line 162, in <lambda>
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
TypeError: can't concat bytes to str

Actually, I don't know what does lambda do but I think that I get this error because of it. Thanks.

Tukanoid
  • 81
  • 2
  • 3
  • 10
  • Possible duplicate of [TypeError: can't concat bytes to str, trying to use python3](http://stackoverflow.com/questions/25042212/typeerror-cant-concat-bytes-to-str-trying-to-use-python3), You need to use bytes everywhere. – Padraic Cunningham Oct 23 '16 at 20:20

1 Answers1

2

you're reading your text file as rb which in python 3 returns a bytes object.

In the function, you're padding with a str object, hence the error. Python 3 clearly separates binary data from text data, a thing that python 2 didn't do.

    PADDING = '{'
    pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING

Change open('Aes/plaintext.txt', 'rb') by open('Aes/plaintext.txt', 'r') and you'll get ascii on both sides, that will work.

(or change PADDING to bytes('{',encoding="ascii") or as James stated just b"{").

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • 1
    Sticking to bytes seems to fit aes encryption, which is a bytes based operation. `PADDING = b'{'` should also work. – James K Oct 23 '16 at 20:20
  • Tnx, but now I have this error: EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s))) expect_byte_string(plaintext) raise TypeError("Only byte strings can be passed to C code") TypeError: Only byte strings can be passed to C code – Tukanoid Oct 31 '16 at 09:55
  • then alternate solution: change PADDING to bytes('{',encoding="ascii") and keep file open as `"rb"`. Tell me how it works for you. – Jean-François Fabre Oct 31 '16 at 14:41