简体   繁体   English

Python密码学Fernet AES加密换行符,缩进,回车

[英]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/ 我必须使用密钥对字符串进行加密并将加密的对象存储为字符串,因为它必须牢固,因此我决定使用提供aes加密的模块“密码学” 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" 如您所见,我制作了一系列函数来轻松使用Fernet加密,但是由于某些原因,它无法处理反斜杠,换行符,缩进和回车符,因此产生的解密与原始字符串不同,此处的测试字符串为"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: 问题是您试图使用str文字而不是bytes.decode()方法将bytes对象转换为string

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' 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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