Jump to content

Python 3 Byte Input Error

Go to solution Solved by colonel_mortis,

You can't use escape characters when inputting data - you have to actually enter the binary value associated with that character, so rather than \x00, you would need the actual NUL character. This is obviously not practical, so there are a couple of different things that you could try. Firstly, rather than generating a random key, get the user to enter a passphrase, then put it through a key derivation function (you could use something like MD5, though usually stronger functions like PBKDF2 are used to make brute force less effective. This means that the user can also remember the key. Alternatively, encode the generated key using either hex or base64, so that the user only has to type ascii characters, then decode what they typed to get what actually needs to be passed into the function as the key.

Python 3.5 windows x64 and up-to-date libs

I'm having an issue passing an AES key. When its generated from os.urandom and set as a variable it works OR when its set as a variable directly(a = b'\x65'). But, when I try to enter it/get it from an input I get an error about "AES key must be 16,24,32 bytes".

I've tried entering it in the form of

Quote

b'~!\x07\x85\xdf\x03\xdaR\xf5:U9\xbe\ro\xa0\x9b9\x88\xed\xa1\x82k\xd3"\x12\xc9\xd7\x86\xe1\xae\xbe'

and

Quote

~!\x07\x85\xdf\x03\xdaR\xf5:U9\xbe\ro\xa0\x9b9\x88\xed\xa1\x82k\xd3"\x12\xc9\xd7\x86\xe1\xae\xbe

both return the same error, at this point I assume it has to do with the python input function. Any ideas for a work around or some modification to the input line? Heres the bit that causes the problem

import os
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(mes, passphrase, key_size=256):
    mes = pad(mes)
    iv = Random.new().read(AES.block_size)
    cipher = AES.new(passphrase, AES.MODE_CBC, iv)
    return iv + cipher.encrypt(mes)
def decrypt(ciphertext, passphrase):
    iv = ciphertext[:AES.block_size]
    cipher = AES.new(passphrase, AES.MODE_CBC, iv)
    plaintext = cipher.decrypt(ciphertext[AES.block_size:])
    return plaintext.rstrip(b"\0")

def encrypt_file(file_name, passphrase):
    with open(file_name, 'rb') as fo:
        plaintext = fo.read()
    enc = encrypt(plaintext, passphrase)
    with open(file_name + ".enc", 'wb') as fo:
        fo.write(enc)
def decrypt_file(file_name, passphrase):
    with open(file_name, 'rb') as fo:
        ciphertext = fo.read()
    dec = decrypt(ciphertext, passphrase)
    with open(file_name[:-4], 'wb') as fo:
        fo.write(dec)


passphrase = os.urandom(32)

print("Passphrase:",passphrase)
encrypt_file('foo.txt', passphrase)
input("Press enter to decrypt")
passphrase = input("Enter passprase:")
decrypt_file('foo.txt.enc', passphrase)

 

                     .
                   _/ V\
                  / /  /
                <<    |
                ,/    ]
              ,/      ]
            ,/        |
           /    \  \ /
          /      | | |
    ______|   __/_/| |
   /_______\______}\__}  

Spoiler

[i7-7700k@5Ghz | MSI Z270 M7 | 16GB 3000 GEIL EVOX | STRIX ROG 1060 OC 6G | EVGA G2 650W | ROSEWILL B2 SPIRIT | SANDISK 256GB M2 | 4x 1TB Seagate Barracudas RAID 10 ]

[i3-4360 | mini-itx potato | 4gb DDR3-1600 | 8tb wd red | 250gb seagate| Debian 9 ]

[Dell Inspiron 15 5567] 

 

 

Link to comment
Share on other sites

Link to post
Share on other sites

I guess that when you pass b'\x4b' thorugh input the in will become 8 byte string, not one byte, as one character to the input become one character in the string returned by the function. What I would do, is to accept two characters hexdecimals like 4b6f4b61 and then in a loop convert those to integer and then each to byte by taking always two character and convert hex to dec.

Link to comment
Share on other sites

Link to post
Share on other sites

You can't use escape characters when inputting data - you have to actually enter the binary value associated with that character, so rather than \x00, you would need the actual NUL character. This is obviously not practical, so there are a couple of different things that you could try. Firstly, rather than generating a random key, get the user to enter a passphrase, then put it through a key derivation function (you could use something like MD5, though usually stronger functions like PBKDF2 are used to make brute force less effective. This means that the user can also remember the key. Alternatively, encode the generated key using either hex or base64, so that the user only has to type ascii characters, then decode what they typed to get what actually needs to be passed into the function as the key.

HTTP/2 203

Link to comment
Share on other sites

Link to post
Share on other sites

@colonel_mortis Thank you, I had a serious blond moment, I added hashing the passwords with sha256

                     .
                   _/ V\
                  / /  /
                <<    |
                ,/    ]
              ,/      ]
            ,/        |
           /    \  \ /
          /      | | |
    ______|   __/_/| |
   /_______\______}\__}  

Spoiler

[i7-7700k@5Ghz | MSI Z270 M7 | 16GB 3000 GEIL EVOX | STRIX ROG 1060 OC 6G | EVGA G2 650W | ROSEWILL B2 SPIRIT | SANDISK 256GB M2 | 4x 1TB Seagate Barracudas RAID 10 ]

[i3-4360 | mini-itx potato | 4gb DDR3-1600 | 8tb wd red | 250gb seagate| Debian 9 ]

[Dell Inspiron 15 5567] 

 

 

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×