使用Cryptodome实现RSA加解密时遇‘RSA密钥格式不支持’错误求助
RSA导入PEM公钥报错“RSA key format is not supported”排查解决
编写了基于非对称加密(RSA)的文件加解密代码,使用PEM格式密钥,但导入公钥时始终收到“RSA key format is not supported”错误。尝试过以字符串形式导入、替换换行符为\n,均未解决问题。以下是相关代码、公钥示例及报错信息:
问题代码
from Cryptodome.PublicKey import RSA from Cryptodome.Cipher import PKCS1_OAEP def encrypt(plain_content, file_publickey): with open(file_publickey, 'rb') as f: print(f.read()) public_key = RSA.importKey(f.read()) rsa_cipher = PKCS1.OAEP.new(public_key) return rsa_cipher.encrypt(plain_content.encode()) def decrypt(encrypted_content, file_privatekey): with open(file_privatekey, 'rb') as f: print(f.read()) private_key = RSA.importKey(f.read()) rsa_cipher = PKCS1_OAEP.new(private_key) return rsa_cipher.decrypt(encrypted_content) def main(): key = RSA.generate(4096) with open('public_key.pem', 'wb') as f: f.write(key.publickey().exportKey('PEM')) with open('private_key.pem', 'wb') as f: f.write(key.exportKey('PEM')) try: with open('test.pdf','rb') as fin: cipher_content = encrypt(fin.read(), 'public_key.pem') with open('test_enc.pdf','rw') as fout: fout.write(cipher_content) with open('test_enc.pdf','rb') as fin: decrypted_content = decrypt(fin.read(), 'private_key.pem') with open('test_dec.pdf','rb') as fout: fout.write(decrypted_content) except Exception as e: print(e) if __name__ == "__main__": main()
生成的PEM公钥示例
-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArMQMiEVSQk+TJMEBmVh1 DknyDELcS0Q3K0qtolUuIh5ZQzGkmQ3O7JCQmuhUtEOVBBWiyIAxyjvoLsTeOEEg DUZ8Pn/UBV0rVMhZNFzVrquaHNE142VOHO3RKNjt8kp+FnfNzmlXnOXRRTKF/81W Mo4315vZIHuhiLwfzH1oamKJJl4FRWe6b0Gofk6NE/pnCkywewXC+MIy/CvQhbqa eTBUhERepa7DxOXQrpqSDwPn7NAnnpvsPXVzYTvrDdtH7v/+E9c6e3qnm6y7i2cc 7Ezlfdxpbkr8Fjqrpd4x3hdQlvoXTpgKo6NLiO+kJH2p8oADlAHpBjyHUeGwCkD6 ss9Ri+zk1O3U2nOzG+5MDQhexU/Q/TXNh0ZalfNJgIlcQFzssnQ/mJx1X68iaVLh J5UW6j4k1UxCnYAopKf5q4av/zkOxecTFAHuzVFjV6teYLb86wTHo1R5osMvKnpH hR2bpzVbVEKHYSRiToyqEFIMBC8QjfqvwprnJMCQglXLx4dbThiJ+w8w01u/nJtS gxnkj4HkHN1GWidsIAPPedCubQS3KxEZMPIW9O+HXXq0RdvY0Zz/rOJzsuY6RY0B vX6L8buwbkemXRmM+NC+d9rL0Ak+LrZ+nL4N7/N1v08oD47xUH5WTYKEX2UCif/F KVggkFk8f3NePn6a7jOrzy8CAwEAAQ== -----END PUBLIC KEY-----
报错信息
b'-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArMQMiEVSQk+TJMEBmVh1\nDknyDELcS0Q3K0qtolUuIh5ZQzGkmQ3O7JCQmuhUtEOVBBWiyIAxyjvoLsTeOEEg\nDUZ8Pn/UBV0rVMhZNFzVrquaHNE142VOHO3RKNjt8kp+FnfNzmlXnOXRRTKF/81W\nMo4315vZIHuhiLwfzH1oamKJJl4FRWe6b0Gofk6NE/pnCkywewXC+MIy/CvQhbqa\neTBUhERepa7DxOXQrpqSDwPn7NAnnpvsPXVzYTvrDdtH7v/+E9c6e3qnm6y7i2cc\n7Ezlfdxpbkr8Fjqrpd4x3hdQlvoXTpgKo6NLiO+kJH2p8oADlAHpBjyHUeGwCkD6\nss9Ri+zk1O3U2nOzG+5MDQhexU/Q/TXNh0ZalfNJgIlcQFzssnQ/mJx1X68iaVLh\nJ5UW6j4k1UxCnYAopKf5q4av/zkOxecTFAHuzVFjV6teYLb86wTHo1R5osMvKnpH\nhR2bpzVbVEKHYSRiToyqEFIMBC8QjfqvwprnJMCQglXLx4dbThiJ+w8w01u/nJtS\ngxnkj4HkHN1GWidsIAPPedCubQS3KxEZMPIW9O+HXXq0RdvY0Zz/rOJzsuY6RY0B\nvX6L8buwbkemXRmM+NC+d9rL0Ak+LrZ+nL4N7/N1v08oD47xUH5WTYKEX2UCif/F\nKVggkFk8f3NePn6a7jOrzy8CAwEAAQ==\n-----END PUBLIC KEY-----' RSA key format is not supported
问题排查与修复
核心问题1:文件读取指针耗尽
在encrypt和decrypt函数中,先调用f.read()打印密钥内容,此时文件指针已移动到文件末尾,第二次f.read()会返回空字节,导致RSA无法解析空内容。
核心问题2:文件打开模式错误
- 加密后写入
test_enc.pdf使用了rw模式,应改为wb(二进制写入,适配加密后的字节流); - 解密后写入
test_dec.pdf使用了rb模式(只读),应改为wb(二进制写入)。
次要问题:代码引用笔误
代码中PKCS1.OAEP.new应为PKCS1_OAEP.new,是导入模块的直接引用错误。
额外提示:RSA加密长度限制
4096位密钥的PKCS1_OAEP加密最大明文长度为4096/8 - 42 = 446字节,无法直接加密大文件(如PDF)。建议使用混合加密:用RSA加密对称密钥(如AES),再用对称密钥加密大文件内容。
修复后的完整代码
from Cryptodome.PublicKey import RSA from Cryptodome.Cipher import PKCS1_OAEP def encrypt(plain_content, file_publickey): with open(file_publickey, 'rb') as f: key_data = f.read() print(key_data) public_key = RSA.importKey(key_data) rsa_cipher = PKCS1_OAEP.new(public_key) # 检查明文长度,适配4096位RSA的PKCS1_OAEP加密限制 if len(plain_content) > 446: raise ValueError("Plain content too long for 4096-bit RSA encryption. Use hybrid encryption for large files.") return rsa_cipher.encrypt(plain_content) def decrypt(encrypted_content, file_privatekey): with open(file_privatekey, 'rb') as f: key_data = f.read() print(key_data) private_key = RSA.importKey(key_data) rsa_cipher = PKCS1_OAEP.new(private_key) return rsa_cipher.decrypt(encrypted_content) def main(): key = RSA.generate(4096) with open('public_key.pem', 'wb') as f: f.write(key.publickey().exportKey('PEM')) with open('private_key.pem', 'wb') as f: f.write(key.exportKey('PEM')) try: # 用小文本测试,避免RSA长度限制问题 test_content = b"This is a test content for RSA encryption." with open('test.txt','wb') as fin: fin.write(test_content) with open('test.txt','rb') as fin: cipher_content = encrypt(fin.read(), 'public_key.pem') with open('test_enc.bin','wb') as fout: fout.write(cipher_content) with open('test_enc.bin','rb') as fin: decrypted_content = decrypt(fin.read(), 'private_key.pem') with open('test_dec.txt','wb') as fout: fout.write(decrypted_content) print("Decryption successful! Check test_dec.txt") except Exception as e: print(e) if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者redcrow
相关产品推荐
相关产品推荐

