【发布时间】: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