使用 RSA SHA1 OAEP MGF1 加密消息后出现错误填充异常

问题描述 投票:0回答:0

我需要先加密一些消息,然后再将其作为 API 中的请求正文发送。我必须在 Python 中执行此操作,我使用的库是 Pycryptodome。从这里开始,当我使用术语 API 时,我指的是供应商提供的 API 端点,而不是 Pycryptodome API。接收者(API 供应商)共享我需要用来加密此消息的证书(RSA 2048 位)。该证书采用二进制格式 (DER),扩展名为 .cer。我需要使用 Pycryptodome 和文档(https://pycryptodome.readthedocs.io/en/latest/src/public_key/rsa.html)导入它,我发现 import_key 方法接受 X.509 证书二进制或 PEM 编码。 API 文档说我需要使用 RSA/NONE/OAEPWithSHA1AndMGF1Padding 进行加密。这是我的代码。

def encrypt_message(message):
        with open('/home/krishna/work/.certificates/random_certificate.cer', 'rb') as _file:
            key_contents = _file.read()
        recipient_key = RSA.import_key(key_contents)
        cipher_rsa = PKCS1_OAEP.new(recipient_key)
        return base64.b64encode(cipher_rsa.encrypt(message.encode())).decode()

看了PKCS1_OAEP.py文件,默认掩码生成函数是MGF1,默认哈希算法是SHA1。因此,我没有在上面代码的new函数中指定这些参数。此外,我需要将此加密消息作为 base64 字符串 (UTF-8) 发送。看了API文档和Pycryptodome文档,觉得这段代码足够加密了。此外,这段代码有点标准,与 Pycryptodome 文档中的代码几乎相同。但是,我收到解密错误,供应商告诉我这是由于“BAD PADDING EXCEPTION”造成的。这不应该发生,因为我使用 OAEP 进行填充并且供应商确认他们也使用 OAEP 进行填充。这对我来说很难调试,因为我没有供应商的私钥。

所以我尝试生成我自己的一对私钥和公钥 (RSA-2048) 并检查我是否能够解密我的消息。呃,我能够解密我的消息。这是使用我自己的密钥进行加密和解密的代码。

def encrypt_message(message):
        with open('/home/krishna/work/.certificates/my_pub.pem', 'rb') as _file:
            pub = _file.read()
        recipient_key = RSA.importKey(pub)
        cipher_rsa = PKCS1_OAEP.new(recipient_key)
        return base64.b64encode(cipher_rsa.encrypt(message.encode())).decode()

def decrypt_message(gibberish):
        with open('/home/krishna/work/.certificates/my_priv.pem', 'rb') as _file:
            priv =  _file.read()
        pvt_key = RSA.importKey(priv)
        cipher_rsa = PKCS1_OAEP.new(pvt_key)
        return cipher_rsa.decrypt(base64.b64decode(gibberish.encode())).decode()

所以我哪里错了?此测试与实际 API 调用之间的主要区别在于,我的密钥是以 PEM 格式生成的,并且扩展名为 .pem。在 API 调用的情况下,我必须使用 DER 格式的 .cer 证书。但我假设 Pycryptodome 正在为我处理这个(来自文档)。

关于这个我还有几个问题

  1. RSA/NONE/OAEPWithSHA1AndMGF1Padding 中什么是 NONE?
  2. Pycryptodome 中的import_key()importKey() 有什么区别?有 2 种方法,看起来 importKey() 没有一些文档。
  3. 使用OAEP会不会出现padding异常?从我从互联网上读到的内容来看,OAEP 是目前最好的方法,不仅在加密期间添加随机性方面,而且我还读到使用它时填充异常非常罕见。

我真的很想知道这里出了什么问题,因为我一无所知。任何建议或帮助将不胜感激。

python-3.x cryptography rsa pycrypto pycryptodome
© www.soinside.com 2019 - 2024. All rights reserved.