Ruby PKCS7加密签名后出现 字符导致解密失败求助
问题原因与解决方法
问题根源
调用OpenSSL::PKCS7.sign时,默认会把输入数据当作文本内容,自动对其进行MIME格式包装(生成带边界、Content-Type头的PKCS7消息),而非直接签名原始的DER二进制数据。这就导致后续通过p7_signed.data提取的内容,并非最初的加密DER字节crypted,而是被MIME编码后的文本(包含额外的\r换行符、MIME头/边界等),解密时自然无法解析成合法的PKCS7结构,抛出nested asn1 error。
解决方法
在签名时添加OpenSSL::PKCS7::BINARY标志,强制OpenSSL直接处理原始二进制数据,跳过自动MIME编码步骤。修改后的代码如下:
# 发送方加密消息 crypted = OpenSSL::PKCS7.encrypt([recipient_cert], "message").to_der # 发送方签名消息,添加BINARY标志避免MIME编码 signed = OpenSSL::PKCS7.sign(sender_cert, sender_key, crypted, nil, OpenSSL::PKCS7::BINARY).to_der # 接收方提取并解密 p7_signed = OpenSSL::PKCS7.new(signed) store = OpenSSL::X509::Store.new p7_signed.verify(nil, store, nil, OpenSSL::PKCS7::NOVERIFY) unsigned = p7_signed.data # 正常解密 OpenSSL::PKCS7.new(unsigned).decrypt(recipient_key, recipient_cert)
补充说明
如果因特殊情况无法修改签名逻辑,也可以在接收方提取data后,对内容进行MIME解码来还原原始DER数据,但这种方式不如添加BINARY标志直接可靠。例如:
# 接收方解码MIME内容 require 'mail' decoded_data = Mail::Encodings::Base64.decode(unsigned) OpenSSL::PKCS7.new(decoded_data).decrypt(recipient_key, recipient_cert)
不过推荐优先使用添加BINARY标志的方案,避免额外的解码步骤和潜在的编码问题。
内容的提问来源于stack exchange,提问作者Jellicle
相关产品推荐
相关产品推荐

