我正在使用加密模块加密一些数据,然后尝试将其存储在我的 SQL 数据库中。当它是一个字符串时,它就起作用了。但是,当我尝试使用元组或字典时,它失败了。我有以下作为我正在调用的函数。 (使用 cryptotography.Fernet.encrypt)。
def encrypt(to_encrypt):
''' Takes a bytestring and returns a token. '''
key = get_key()
f = make_fernet_object(key)
token = f.encrypt(to_encrypt)
return token
如果我尝试直接将元组或字典传递给它,我会得到
类型错误:数据必须是字节。
如果我使用
bytes(my_tuple)
然后我明白了
类型错误:“str”对象无法解释为整数
如何将我的元组(包含 2 个字符串和一个字典)转换为 Fernet 将加密的字节对象,以便我可以将 blob 放入我的 SQL 数据库中?
编辑 - 有问题的元组的格式为..
my_tuple = ('username', 'password', {'memorable question':'memorable answer', 'memorable question 2', 'memorable answer 2'})
正如您的错误消息所示,
encrypt
仅接受字节作为输入。您可以将字符串格式化为字节,但不能将元组格式化,元组是 Python 对象的序列。您可以将元组中包含的两个字符串中的任何一个传递给 bytes()
,或者将它们分隔并连接为单个字符串并传递它,但不能传递元组本身(不指定将其转换为字符串并恢复的方法)表示字符串作为元组)。
https://cryptography.io/en/latest/_modules/cryptography/fernet/
我假设您的数据是强类型的
喜欢
tuple[str, str, dict[str, str]]
在这种情况下,这可能会有所帮助(如果没有,也许会有所帮助,但更难)
我定义了一个可以序列化字节可迭代的类(我将它放在底部)
它只是(反)序列化多个东西,你只需要告诉它要序列化什么
然后你可以在你的情况下使用它,比如
obj = my_tuple = ('username', 'password', {'memorable question':'memorable answer', 'memorable question 2': 'memorable answer 2'})
serialized = ArgsToBytes.argsToBytes(serializeStr(obj[0]), serializeStr(obj[1]), ArgsToBytes.argsToBytes(*(ArgsToBytes.argsToBytes(serializeStr(k), serializeStr(v)) for (k, v) in obj[2].items())))
# serialized == b'8:username8:password96:42:18:memorable question16:memorable answer0:46:20:memorable question 218:memorable answer 20:0:0:'
a = ArgsToBytes.bytesToArgs(serialized)
# a == [b'username', b'password', b'42:18:memorable question16:memorable answer0:46:20:memorable question 218:memorable answer 20:0:']
b = ArgsToBytes.bytesToArgs(a[2])
# b == [b'18:memorable question16:memorable answer0:', b'20:memorable question 218:memorable answer 20:']
c = dict(ArgsToBytes.bytesToArgs(x) for x in b)
#c == {b'memorable question': b'memorable answer', b'memorable question 2': b'memorable answer 2'}
如你所见,这里写得有点多了
理想情况下,您可以将事物分为类和函数
class ArgsToBytes:
@staticmethod
def argsToBytes(*args) -> bytes:
serialized = b"";
for arg in args:
if not isinstance(arg, bytes): arg = bytes(arg);
length = len(arg);
serialized += str(length).encode("ascii") + b":" + arg;
pass
serialized += b"0:";
return serialized;
pass
@staticmethod
def bytesToArgs(serialized: bytes) -> list:
result = [];
i = 0;
while True:
index = serialized.index(b":", i);
length = serialized[i : index];
i = index + 1;
length = int(length.decode("ascii"));
if length == 0: break;
index = i + length;
result.append(serialized[i : index]);
i = index;
pass
return result;
pass
pass