Python中RSA PKCS1_OAEP加密填充错误导致解密失败问题
RSA加密解密填充错误及异常长度问题解决
问题分析
- 加密结果长度异常:RSA加密输出长度固定等于密钥字节长度(2048位密钥对应256字节),你提到的214~380字节属于异常,大概率是密钥导入错误或代码执行环节出问题。
- 填充验证失败:PyCryptodome与OpenSSL的PKCS1_OAEP默认参数可能不匹配,导致解密时填充校验不通过。
解决方案
1. 确认密钥正确性与加密结果长度
首先验证加密结果长度是否符合预期,在加密代码中添加长度校验:
from Crypto.Cipher import PKCS1_OAEP from Crypto.PublicKey import RSA from base64 import b64decode txt = "hello" pubkey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxfLqdKTtAFwh8lPf/sjE6N3rPZqyjHNYglGQRPJ6sHHs0Ciw18v8R4eVEIwdGslFDvg3usP1PMQrW9Nyy16Sz4T5lUyPTZFgvQ0xyB1HH9gqyprxV7Rcdb5iRLj3HuUG8Bg/4mWvp5I69GpZcpPFwm0T7Y8Np1ouErf6f+Yp6c4X0JQ5Cm8EIGmom0mRw93uouYXZ+P8WMd/EEdgRl8vJpgkewt99lm5SPsW3742bgfnsT38Z2vJMziXtVIPVsdH5yKGe0arAYIY6UHC+JnOS/KjBZ609Px5Z785ZrppXiVEX0K4e294S5xhpzPuNLTAsYPfLWDjwaLZGN8hGvFSCwIDAQAB" keyDER = b64decode(pubkey) publickey = RSA.importKey(keyDER) encryptor = PKCS1_OAEP.new(publickey) encrypted = encryptor.encrypt(bytes(txt, "utf-8")) # 校验加密结果长度,2048位密钥应输出256 print(f"加密结果长度:{len(encrypted)}") with open("file.encrypted", "wb") as f: f.write(encrypted)
如果长度不是256,检查pubkey变量是否正确赋值(无多余空格、换行),确认密钥导入过程无错误。
2. 统一PKCS1_OAEP参数
PyCryptodome与OpenSSL的OAEP默认参数可能存在差异,需显式对齐:
方式一:修改加密代码对齐OpenSSL默认参数
OpenSSL 1.1.1s的rsautl -oaep默认使用SHA-1作为哈希函数和MGF1哈希函数,修改加密代码如下:
from Crypto.Cipher import PKCS1_OAEP from Crypto.PublicKey import RSA from Crypto.Hash import SHA1 from base64 import b64decode txt = "hello" pubkey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxfLqdKTtAFwh8lPf/sjE6N3rPZqyjHNYglGQRPJ6sHHs0Ciw18v8R4eVEIwdGslFDvg3usP1PMQrW9Nyy16Sz4T5lUyPTZFgvQ0xyB1HH9gqyprxV7Rcdb5iRLj3HuUG8Bg/4mWvp5I69GpZcpPFwm0T7Y8Np1ouErf6f+Yp6c4X0JQ5Cm8EIGmom0mRw93uouYXZ+P8WMd/EEdgRl8vJpgkewt99lm5SPsW3742bgfnsT38Z2vJMziXtVIPVsdH5yKGe0arAYIY6UHC+JnOS/KjBZ609Px5Z785ZrppXiVEX0K4e294S5xhpzPuNLTAsYPfLWDjwaLZGN8hGvFSCwIDAQAB" keyDER = b64decode(pubkey) publickey = RSA.importKey(keyDER) # 显式指定哈希函数与MGF1参数 encryptor = PKCS1_OAEP.new(publickey, hashAlgo=SHA1.new(), mgfHash=SHA1.new()) encrypted = encryptor.encrypt(bytes(txt, "utf-8")) with open("file.encrypted", "wb") as f: f.write(encrypted)
方式二:修改解密命令对齐PyCryptodome默认参数
若不想修改加密代码,在OpenSSL解密时显式指定与PyCryptodome默认匹配的参数:
openssl rsautl -oaep -digest sha1 -mgf1-digest sha1 -decrypt -inkey claveprivada.pem -in file.encrypted -out key.txt
3. 验证密钥配对
确保公钥和私钥是配对的,用OpenSSL命令对比模数:
# 从公钥提取模数 echo "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxfLqdKTtAFwh8lPf/sjE6N3rPZqyjHNYglGQRPJ6sHHs0Ciw18v8R4eVEIwdGslFDvg3usP1PMQrW9Nyy16Sz4T5lUyPTZFgvQ0xyB1HH9gqyprxV7Rcdb5iRLj3HuUG8Bg/4mWvp5I69GpZcpPFwm0T7Y8Np1ouErf6f+Yp6c4X0JQ5Cm8EIGmom0mRw93uouYXZ+P8WMd/EEdgRl8vJpgkewt99lm5SPsW3742bgfnsT38Z2vJMziXtVIPVsdH5yKGe0arAYIY6UHC+JnOS/KjBZ609Px5Z785ZrppXiVEX0K4e294S5xhpzPuNLTAsYPfLWDjwaLZGN8hGvFSCwIDAQAB" | base64 -d > pubkey.der openssl rsa -pubin -inform der -in pubkey.der -text -noout # 从私钥提取模数 openssl rsa -in claveprivada.pem -text -noout
对比两者的Modulus字段,若不一致说明密钥不配对,需更换为配对密钥。
内容的提问来源于stack exchange,提问作者vincegeratorix
相关产品推荐
相关产品推荐

