You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:04:53