【问题标题】:Python Cryptography Fernet AES Encryption newlines, indents, carriage returnsPython Cryptography Fernet AES 加密换行、缩进、回车
【发布时间】:2019-03-12 19:54:04
【问题描述】:

我必须使用密钥加密字符串并将加密对象存储为字符串,它必须很强大所以我决定使用提供 aes 加密“密码学”https://pypi.org/project/cryptography/的模块

如你所见,我制作了一系列函数来轻松使用 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

如果有人可以为此特定代码或可以满足我需要的不同加密算法提供解决方案

【问题讨论】:

  • 您的代码对于任何输入字符串都失败,因为您正在对密文进行切片; Fernet.decrypt() 期望 Fernet.encrypt() 的完整输出。此外,这是处理异常的一种非常糟糕的方式。
  • @t.m.adam 不是真的,如果你用另一个不包含任何反斜杠的字符串测试它,你会看到。关于异常,这些函数都是我自己用的,我不需要调试,我只需要知道它是否失败,没有人会这样做
  • 好吧,我认为您的代码需要调试,如果没有,它就不会在这里。无论如何,默默地捕获所有异常都是不好的做法。您的代码为我的机器上的两个字符串生成 False(使用 Python 2.7,密码学 v1.7.2 测试)。你为什么要对数据进行切片?
  • @citizen2077 使用 much 更简单的实现它不会表现出这种行为(仅使用随机生成的 fernet 密钥)s = 'hi\tthere'; enc=f.encrypt(s.encode()); s == f.decrypt(enc).decode() 产生 True。我会认真看看你的 decrypt_string 方法和你实现的切片

标签: python python-3.x encryption cryptography


【解决方案1】:

问题是您尝试使用 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' 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-15
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 1970-01-01
    • 1970-01-01
    • 2022-12-30
    相关资源
    最近更新 更多