以下代码
key = sec.generateAESKey()
print(key, ': ', len(key))
key = b64encode(key)
print(key, ': ', len(key))
key = sec.encryptAsymmetric(str(key))
key = sec.decryptAsymmetric(key)
print(key, ': ', len(key))
key = b64decode(key)
print(key, ': ', len(key))
输出
b'\xae\xfe\x8\xbe\x86=\xe8\x979/@\xf58\xf9\x95':16
b'rv6LuL6GPeiXOS9A9Tj5lQ==':24
b'rv6LuL6GPeiXOS9A9Tj5lQ==':27
b'n\xbb\xfa。\xe2\xfa\x18\xf7\xa2\\xe4\xbd\x03\xd4\xe3\xe6T':17
正如你所看到的,不对称加密和解密出现了问题,因为密钥在b64解码之前增加了3个字节,在之后增加了1个字节
基本功能是:
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP
from Cryptodome.Cipher import AES
from Cryptodome.Random import get_random_bytes
from Cryptodome.Hash import SHA256
from base64 import b64decode
from base64 import b64encode
import re
# important global vars, don't need to re-generate these
public_key_plain = open("public.pem").read()
public_key = RSA.import_key(public_key_plain)
private_key = RSA.import_key(open("private.pem").read())
# constants
KEY_SIZE = 16
AUTH_TOKEN_EXPIRY = 15 # minutes
# encrypt using our public key
# data should be in a string format
def encryptAsymmetric(data):
# convert the data to utf-8
data = data.encode("utf-8")
# generate the cipher
cipher = PKCS1_OAEP.new(public_key, hashAlgo=SHA256)
# encrypt
return b64encode(cipher.encrypt(data))
# decrypt some cipher text using our private key
def decryptAsymmetric(ciphertext):
# generate the cipher
cipher = PKCS1_OAEP.new(private_key, hashAlgo=SHA256)
# decrypt
return cipher.decrypt(b64decode(ciphertext)).decode()
# generates a key for aes
def generateAESKey():
return get_random_bytes(KEY_SIZE)
上面生成此错误的代码是在后端编写的一些单元测试的一部分。当客户端进行非对称加密,而服务器进行解密时,这些功能工作得非常好。出于某种原因,它在这里失败了,但我不明白为什么。如果有人能看到不对称加密和解密的问题,以及为什么要更改密钥,那将非常有帮助。提前感谢
我不能用你的方式复制,因为我没有你的.pem文件,但我可以喜欢这样:
>>> key = b'rv6LuL6GPeiXOS9A9Tj5lQ=='
>>> print(key, ': ', len(key))
b'rv6LuL6GPeiXOS9A9Tj5lQ==' : 24
>>> key = str(key)
>>> print(key, ': ', len(key))
b'rv6LuL6GPeiXOS9A9Tj5lQ==' : 27
这三个额外的字符只是开头的b'
和结尾的'
。如果您使用repr
打印表示,就会看到它:
>>> key = b'rv6LuL6GPeiXOS9A9Tj5lQ=='
>>> print(repr(key), ': ', len(key))
b'rv6LuL6GPeiXOS9A9Tj5lQ==' : 24
>>> key = str(key)
>>> print(repr(key), ': ', len(key))
"b'rv6LuL6GPeiXOS9A9Tj5lQ=='" : 27
在原始密钥中,b'
和'
是而不是bytes
-字符串的一部分,它们只是表明它是bytes
-字符串及其边界。就像str
字符串周围的"
不是该字符串的一部分一样。但在那个字符串中,b'
和'
是字符串的部分。
不确定为什么要将bytes
转换为str
,但不应该使用str(key)
。我会使用它的decode()
方法。然后一切都很好,你有一个没有额外字符的str
字符串:
>>> key = b'rv6LuL6GPeiXOS9A9Tj5lQ=='
>>> print(repr(key), ': ', len(key))
b'rv6LuL6GPeiXOS9A9Tj5lQ==' : 24
>>> key = key.decode()
>>> print(repr(key), ': ', len(key))
'rv6LuL6GPeiXOS9A9Tj5lQ==' : 24
看起来str()
方法向已经基本的64编码数据添加了3个字节。
基64编码器返回ASCII编码的字节。因此,基本64编码器不只是返回一个字符串(用于文本(,而是返回字节。现在,如果您将它们转换为字符串,那么它可能会发现只是包含ASCII。然而,Python中的标准编码器似乎总是在重新生成完整字符串时添加3个字节,因为__str__
方法在bytes
实例上使用。
仅使用str(key, encoding='ascii')
将字节解码为ASCII似乎就消除了这个问题。然而,对此最好使用显式decode
方法。
因为这个出色的答案而编辑了答案。我想我应该再看看实际的字节数。