Search code examples
pythonpython-3.xaes

Why do I get an extra b prefix when reading Bytes?


I am trying to read the content of an external file that contains a ciphered text in a Byte format with the following code:

import pyaes
def decryption_method():
    key = 'storochkraftfullsverige'
    # the problem comes here
    with open('encrypted.txt', 'rb') as f:
        ciphertext = f.read()
    print(type(ciphertext)) # this indicates that the variable is of type bytes

    key = key.encode('utf-8')            
    aes = pyaes.AESModeOfOperationCTR(key)
    decrypted = aes.decrypt(ciphertext).decode('utf-8')
    return decrypted

However, when reading the external file I get the following result:

b"b'a`_\xc1\x9f\xd4J\xdc\xcd'"

instead of

b'a`_\xc1\x9f\xd4J\xdc\xcd'

My questions are:

  1. Why am I getting the extra prefix when reading the external file? How could I read the file without the extra prefix?
  2. Is there a way to select only the Bytes I want and then append them in a BytesArray object?

Any suggestion or further clarification is well received :)

If you want to do your own tests you can use the following code to encrypt and decrypt by using AES in Python 3.x

import pyaes

key = "Your key file that will be used to encrypt and decrypt."
plaintext = "This text will be encrypted and decrypted."

# key must be bytes, so we convert it
key = key.encode('utf-8')

aes = pyaes.AESModeOfOperationCTR(key)    
ciphertext = aes.encrypt(plaintext)

# show the encrypted data
print (ciphertext)

# DECRYPTION
aes = pyaes.AESModeOfOperationCTR(key)

# decrypted data is always binary, need to decode to plaintext
decrypted = aes.decrypt(ciphertext).decode('utf-8')

# True
print (decrypted == plaintext)

Solution

  • Without having access to the exact file you are using it is difficult to say, but, this is likely an issue with the contents of the file.

    Using your example, I modified it so that it would write out a ciphertext file (as raw bytes) and read it in (as raw bytes).

    import pyaes
    
    # Key length was invalid, so I changed it
    key = 'This_key_for_demo_purposes_only!'
    plaintext = "This text will be encrypted and decrypted."
    
    # key must be bytes, so we convert it
    key = key.encode('utf-8')
    
    aes = pyaes.AESModeOfOperationCTR(key)    
    ciphertext = aes.encrypt(plaintext)
    
    # show the encrypted data
    print (ciphertext)
    
    # Write out raw bytes to file
    with open('ciphertext.txt', 'wb') as file_out:
        file_out.write(ciphertext)
    
    ciphertext = None
    print(ciphertext)
    
    # Read in raw bytes from file
    with open('ciphertext.txt', 'rb') as file_in:
        ciphertext = file_in.read()
    
    print(ciphertext)
    
    # DECRYPTION
    aes = pyaes.AESModeOfOperationCTR(key)
    
    # decrypted data is always binary, need to decode to plaintext
    decrypted = aes.decrypt(ciphertext).decode('utf-8')
    
    # True
    print (decrypted == plaintext)
    

    Then, using the decryption_method() I was able to decrypt the ciphertext file:

    import pyaes
    
    def decryption_method():
        # The key length was invalid, so I used a different one for this example.
        key = 'This_key_for_demo_purposes_only!'
        with open('ciphertext.txt', 'rb') as f:
            ciphertext = f.read()
    
        key = key.encode('utf-8')
        aes = pyaes.AESModeOfOperationCTR(key)
        decrypted = aes.decrypt(ciphertext).decode('utf-8')
        return decrypted
    
    print(decryption_method())
    

    This outputs the plaintext as expected on my machine, so I don't suspect there is anything wrong with your code; rather, the file content is the likely culprit here.