简体   繁体   中英

Python Cryptography Fernet AES Encryption newlines, indents, carriage returns

I have to encrypt a string with a key and store the encrypted object as a string, it has to be strong so I decided to use a module providing aes encryption "Cryptography" https://pypi.org/project/cryptography/

As you can see, I made a series of functions to make easy use of Fernet encryption, however for some reason it cannot handle backslashes, newlines, indents and carriage returns, the resulting decryption being different than the original string, the test string here is "t\\n\\t"

from cryptography.fernet import Fernet
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
import base64

def encrypt_string(string_, password, f = None):
    if f is None:
        f = get_fernet_(password)
    try:
        return str(f.encrypt(string_.encode()))[2:- 1]
    except:
        return None

def decrypt_string(string_, password, f = None):
    if f is None:
        f = get_fernet_(password)
    try:
        return str(f.decrypt(string_.encode()))[2:- 1]
    except:
        return None

def get_fernet_(password):
    if password and isinstance(password,str):
        kdf = PBKDF2HMAC(algorithm = hashes.SHA256(),
                         length = 32,
                         salt = password.encode(),
                         iterations = 100000,
                         backend = default_backend())
        key = base64.urlsafe_b64encode(kdf.derive(password.encode()))
        f = Fernet(key)
        return f

def test_encryption(s = "text", password = "key"):
    my_f = get_fernet_(password)
    s2 = encrypt_string(s, password)
    s3 = decrypt_string(s2, password)
    s4 = encrypt_string(s, password, my_f)
    s5 = decrypt_string(s4, password, my_f)
    if s == s3 and s == s5:
        return True
    return False

print (test_encryption("text"))
True

print (test_encryption("t\n\t"))
False

If anyone could provide a solution for this particular code or a different encryption algorithm that can do what I need

The problem is you are trying to convert a bytes object to a string using the str literal, rather than the bytes.decode() method:

from cryptography.fernet import Fernet

# Im just using a random key for simplicity
key = Fernet.generate_key()
f = Fernet(key)

mystr = 'hi\tthere'

enc = f.encrypt(mystr.encode()) # str.encode() creates a bytes object
dec = f.decrypt(enc)

str(dec)
# "b'hi\\tthere'"
# This is NOT the same, use decode

mystr==str(dec[2:-1]) # returns False
mystr==dec.decode() # returns True

dec.decode()
# 'hi\tthere' 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM