如何通过OpenSSL命令行解密PyCryptodome加密文件?或修改代码实现
使用PyCryptodome加密的文件能否通过OpenSSL命令行解密?
嘿,直接给你答案:你当前的加密代码生成的文件没办法直接用OpenSSL命令行解密。原因很简单——你自定义了加密后的数据格式(把加密的会话密钥、nonce、tag、密文直接按顺序拼接),而OpenSSL只认特定的标准格式(比如PKCS#7/SMIME或者它自己的信封格式),它没法自动识别你拼接的各个二进制块分别是什么。
先把你的原有代码贴出来方便参考:
你的原有加密代码
from Crypto.PublicKey import RSA from Crypto.Random import get_random_bytes from Crypto.Cipher import AES, PKCS1_OAEP key = RSA.generate(2048) secret_key = key.exportKey(passphrase='letmein', pkcs=8, protection='scryptAndAES128-CBC') public_key = key.publickey().exportKey() rsa_key = RSA.importKey(public_key) session_key = get_random_bytes(16) cipher_rsa = PKCS1_OAEP.new(rsa_key) cipher_aes = AES.new(session_key, AES.MODE_EAX) ciphertext, tag = cipher_aes.encrypt_and_digest(data) dst.write(cipher_rsa.encrypt(session_key)) dst.write(cipher_aes.nonce) dst.write(tag) dst.write(ciphertext)
你的原有解密代码
rsa_key = RSA.importKey(secret_key, 'letmein') enc_session_key, nonce, tag, ciphertext = [ src.read(x) for x in (rsa_key.size_in_bytes(), 16, 16, -1) ] cipher_rsa = PKCS1_OAEP.new(rsa_key) session_key = cipher_rsa.decrypt(enc_session_key) cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce) decoded = cipher_aes.decrypt_and_verify(ciphertext, tag)
怎么修改代码让OpenSSL能解密?
有两种可行的方案,推荐第一种标准格式的方式,更稳定通用:
方案1:生成PKCS#7(SMIME)标准格式(推荐)
PKCS#7是OpenSSL原生支持的加密格式,PyCryptodome也能直接生成这种格式。修改后的加密代码如下:
from Crypto.PublicKey import RSA from Crypto.Random import get_random_bytes from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.PKCS7 import PKCS7 from Crypto.Hash import SHA256 # 生成RSA密钥对(和你原来的逻辑一致) key = RSA.generate(2048) secret_key = key.exportKey(passphrase='letmein', pkcs=8, protection='scryptAndAES128-CBC') public_key = key.publickey() # 假设data是你要加密的原始字节数据 # data = open("your_file.txt", "rb").read() # 生成AES-GCM会话密钥并加密数据(GCM比EAX更符合PKCS#7的常见用法,OpenSSL支持也更完善) session_key = get_random_bytes(16) cipher_aes = AES.new(session_key, AES.MODE_GCM) ciphertext, tag = cipher_aes.encrypt_and_digest(data) # 构建PKCS#7加密信封 pkcs7 = PKCS7() pkcs7.set_content(ciphertext) # 添加接收者(用你的RSA公钥加密会话密钥,PKCS1_OAEP填充和你原来的逻辑一致) pkcs7.add_recipient( public_key, session_key, cipher_algorithm=(AES, 128), padding=PKCS1_OAEP, digest_algo=SHA256 ) # 设置GCM模式需要的nonce和验证标签 pkcs7.set_aead_params(nonce=cipher_aes.nonce, tag=tag) # 编码成DER格式的PKCS#7文件 pkcs7_der = pkcs7.encode() with open("encrypted.p7m", "wb") as dst: dst.write(pkcs7_der) # 顺便把私钥保存成PEM文件,方便OpenSSL使用 with open("private_key.pem", "wb") as f: f.write(secret_key)
用OpenSSL解密的命令
现在直接用这条命令就能解密:
openssl smime -decrypt -in encrypted.p7m -inkey private_key.pem -out decrypted_file.txt
输入私钥的密码(你设置的letmein)就能得到解密后的文件了。
方案2:调整自定义格式,用OpenSSL分步解密
如果你不想用PKCS#7,也可以拆分加密后的各个组件,让OpenSSL能分步处理:
修改后的加密代码
from Crypto.PublicKey import RSA from Crypto.Random import get_random_bytes from Crypto.Cipher import AES, PKCS1_OAEP key = RSA.generate(2048) secret_key = key.exportKey(passphrase='letmein', pkcs=8, protection='scryptAndAES128-CBC') public_key = key.publickey().exportKey() rsa_key = RSA.importKey(public_key) session_key = get_random_bytes(16) cipher_rsa = PKCS1_OAEP.new(rsa_key) enc_session_key = cipher_rsa.encrypt(session_key) cipher_aes = AES.new(session_key, AES.MODE_EAX) ciphertext, tag = cipher_aes.encrypt_and_digest(data) # 把各个组件分别保存,或者按固定格式拼接但留好标识(这里推荐分别保存) with open("enc_session_key.bin", "wb") as f: f.write(enc_session_key) with open("nonce.bin", "wb") as f: f.write(cipher_aes.nonce) with open("tag.bin", "wb") as f: f.write(tag) with open("ciphertext.bin", "wb") as f: f.write(ciphertext) # 保存私钥 with open("private_key.pem", "wb") as f: f.write(secret_key)
用OpenSSL分步解密的命令
# 第一步:用RSA私钥解密会话密钥 openssl rsautl -decrypt -inkey private_key.pem -in enc_session_key.bin -out session_key.bin -oaep # 第二步:用AES-EAX解密数据(需要OpenSSL 1.1.0及以上版本支持EAX模式) openssl aes-128-eax -d \ -in ciphertext.bin \ -out decrypted_file.txt \ -K $(xxd -p session_key.bin) \ -iv $(xxd -p nonce.bin) \ -tag $(xxd -p tag.bin)
这种方式需要手动处理各个组件,容易出错,不如方案1省心。
总结
- 你当前的自定义拼接格式OpenSSL没法识别,因为没有遵循标准结构。
- 优先选择方案1生成PKCS#7格式,这是行业标准,不仅OpenSSL能解,其他支持SMIME的工具也能处理。
- 如果非要用自定义格式,就拆分组件用分步命令解密,但要确保各个文件的字节长度完全正确。
内容的提问来源于stack exchange,提问作者jsmesami
相关产品推荐
相关产品推荐

