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

如何通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:13:50