首页 > 解决方案 > 进行 RSA 加密然后解密 AES 密钥的奇怪错误

问题描述

以下代码

    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\x8b\xb8\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

如您所见,非对称加密和解密出现问题,因为密钥在 b64decoding 之前获得 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)

上面生成此错误的代码是在后端编写的一些单元测试的一部分。当客户端进行非对称加密而服务器进行解密时,这些功能可以正常工作。出于某种原因,它在这里失败了,但我不明白为什么。如果有人能看到非对称加密和解密有什么问题,以及为什么它会更改真正有用的密钥。提前致谢

标签: pythonsecurity

解决方案


因为我没有你的 .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'and'不是-string一部分bytes,它们只是表明它是bytes-string 及其边界。就像-string"周围的str不是该字符串的一部分。但是在那个字符串中,b'and' 字符串的一部分。

不知道你为什么将你的转换bytesstr,但你不应该使用str(key). 我会使用它的decode()方法。那么这一切都很好,你有一个str-string 没有那些额外的字符:

>>> key = b'rv6LuL6GPeiXOS9A9Tj5lQ=='
>>> print(repr(key), ': ', len(key))
b'rv6LuL6GPeiXOS9A9Tj5lQ==' :  24

>>> key = key.decode()
>>> print(repr(key), ': ', len(key))
'rv6LuL6GPeiXOS9A9Tj5lQ==' :  24

推荐阅读