Search code examples
pythoncryptographyfernet

Python Fernet encrypt and decrypt problem with bytes


I am coding a python file encrypter with fernet module; I want encrypt part of the file bytes for increase the speed of proccess... (Not full of that) I couldn't see a problem during this action but the result was not good! The decrypted file was broken!

Encrypt.py :

from cryptography.fernet import Fernet

motherFuckerCipher = Fernet.generate_key()


with open('myCode.txt','wb') as filekey:
    filekey.write(motherFuckerCipher)


# Encrypt the files such a good boy!

with open("myCode.txt","rb") as mobinsKey:
    mobin = mobinsKey.read()

fernet = Fernet(mobin)

with open("sikish.jpg","rb") as file:
    original = file.read()


# print(original)
selectedStr = original[0:100]
notSelectedStr = original[100:]
# print(notSelectedStr)
encrypted = fernet.encrypt(selectedStr)
# print(encrypted)
lengthOfEncryptedString = len(encrypted)

fullSource = str(lengthOfEncryptedString).encode("utf-8") + b"@@" + encrypted + b"@@" + notSelectedStr


with open("encryptedSikish.jpg","wb") as file:
    file.write(fullSource)

decrypt.py :

from cryptography.fernet import Fernet

with open("encryptedSikish.jpg","rb") as file:
    encrypted = file.read()

with open("myCode.txt","rb") as code:
    mykey = code.read()

fernet = Fernet(mykey)



# print("{} | {}".format(encrypted,mykey))


# Decrypt like mobin from my life!
allString = str(encrypted).split("@@")

print(allString[2])

decrypted = fernet.decrypt(allString[1])



with open("DecryptedSikish.jpg","wb") as finalfile:
    finalfile.write(decrypted + allString[2].encode("utf-8"))

Please help me... I coded a basic file for check and anylyze the difference between original file and decrypted file, But I don't know what is problem!

Thanks.


Solution

  • The problem is how you're parsing the ciphertext that you've formatted to isolate the encrypted portion of the result from the unencrypted portion. You can use b'@@' to separate these parts, but since the first part is the length of the ciphertext, you only need to separate this length from the ciphertext. The splitting should be done as a bytes object, not a string. If you don't use the maxsplit argument of split you may get extraneous split from your unencrypted portion.

    So, trying to be faithful to your scheme, encryption should look something like

    motherFuckerCipher = Fernet.generate_key()
    
    with open('data_files/myCode.txt', 'wb') as filekey:
        filekey.write(motherFuckerCipher)
    
    with open("data_files/myCode.txt", "rb") as mobinsKey:
        mobin = mobinsKey.read()
    
    fernet = Fernet(mobin)
    
    with open("data_files/sikish.jpg", "rb") as file:
        original = file.read()
    
    selectedStr = original[0:100]
    notSelectedStr = original[100:]
    encrypted = fernet.encrypt(selectedStr)
    lengthOfEncryptedString = len(encrypted)
    
    fullSource = str(lengthOfEncryptedString).encode("utf-8") + b"@@" + encrypted + notSelectedStr
    
    with open("data_files/encryptedSikish.jpg", "wb") as file:
        file.write(fullSource)
    

    and decryption (sorry, I just had to change the variable names)

    with open("data_files/encryptedSikish.jpg", "rb") as file:
        encrypted = file.read()
    
    with open("data_files/myCode.txt", "rb") as code:
        mykey = code.read()
    
    fernet = Fernet(mykey)
    
    all_bytes = encrypted.split(b"@@", maxsplit=1)
    len_cipher = int(all_bytes[0].decode("utf-8"))
    ciphertext = all_bytes[1][:len_cipher]
    unencrypted = all_bytes[1][len_cipher:]
    decrypted = fernet.decrypt(ciphertext)
    
    with open("data_files/DecryptedSikish.jpg", "wb") as finalfile:
        finalfile.write(decrypted + unencrypted)
    
    

    You should try to use Python style conventions. So, for example: selectedStr should instead be selected_str, and really it should be selected_bytes.