Python中如何用.cer文件实现AES加密?转换公钥后遇密钥长度错误
首先得明确:你从.cer文件提取的**公钥是用于非对称加密算法(比如RSA)**的,而AES是对称加密算法,需要的是固定长度的对称密钥(16/24/32字节)——这两者完全不是一回事,直接把公钥当AES密钥用肯定会报长度错误,因为RSA公钥的长度远大于AES要求的字节数。
接下来给你讲正确的解决方案:在实际场景中,我们通常会结合AES和RSA的优势来实现安全加密——用AES加密大体积数据(因为AES速度快),然后用RSA公钥加密AES密钥(因为RSA可以安全地传输密钥,只有持有对应私钥的人才能解密出AES密钥)。
具体操作步骤(以Python为例)
我们用pycryptodome库来实现,先安装依赖:
pip install pycryptodome
1. 加载你提取的RSA公钥
from Crypto.PublicKey import RSA from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.Random import get_random_bytes # 加载PEM格式的公钥文件 with open("public_key.pem", "rb") as f: public_key = RSA.import_key(f.read())
2. 生成符合要求的AES密钥
根据加密强度选择对应长度:
- 16字节 → AES-128(常用)
- 24字节 → AES-192
- 32字节 → AES-256
# 生成16字节的AES-128密钥 aes_key = get_random_bytes(16)
3. 用AES加密你的数据
AES需要指定加密模式(这里用通用的CBC模式)和初始化向量(IV,必须16字节),同时要把数据填充到AES块大小的倍数:
# 生成随机初始化向量IV iv = get_random_bytes(16) aes_cipher = AES.new(aes_key, AES.MODE_CBC, iv) # 准备要加密的数据 raw_data = b"你需要加密的内容" # PKCS7填充:把数据补到AES块大小的倍数 padding_length = AES.block_size - len(raw_data) % AES.block_size padded_data = raw_data + bytes([padding_length]) * padding_length # 执行加密 encrypted_data = aes_cipher.encrypt(padded_data)
4. 用RSA公钥加密AES密钥
这一步是为了安全传输AES密钥——只有持有对应RSA私钥的人,才能解密出AES密钥进而获取原始数据:
rsa_cipher = PKCS1_OAEP.new(public_key) encrypted_aes_key = rsa_cipher.encrypt(aes_key)
5. 加密结果的保存/传输
你需要把encrypted_aes_key(加密后的AES密钥)、iv(初始化向量)、encrypted_data(加密后的原始数据)这三个部分一起保存或发送给接收方。解密时,接收方会先用RSA私钥解密出AES密钥,再结合IV解密出原始数据。
为什么你之前会报错?
你提取的RSA公钥长度通常是2048位(256字节)或者4096位(512字节),远大于AES要求的16/24/32字节,直接把它传给AES加密函数,自然会触发ValueError: AES key must be either 16, 24, or 32 bytes long这个错误。
另外,你之前用openssl提取公钥的命令是完全正确的:
openssl x509 -inform der -pubkey -noout -in certificate_name.cer >public_key.pem
这个命令成功把DER格式的.cer证书里的公钥提取成了PEM格式,方便后续代码加载使用。
内容的提问来源于stack exchange,提问作者Projjol

