在AES密钥上进行RSA加密然后解密的奇怪错误



以下代码

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方法。


因为这个出色的答案而编辑了答案。我想我应该再看看实际的字节数。

相关内容

最新更新