使用 Ruby 的 OpenSSL 库,当我尝试将消息加密并签名为 PKCS7 时,我发现插入了一些额外的
\r
字符,并且我无法解密该消息。
下面我有一个玩具示例。我可以在此粘贴上获得更全面的示例。
# The sender encrypts the message
crypted = OpenSSL::PKCS7.encrypt([recipient_cert], "message").to_der
# The sender signs the message
signed = OpenSSL::PKCS7.sign(sender_cert, sender_key, crypted).to_der
# The recipient extracts data from the signed PKCS7
p7_signed = OpenSSL::PKCS7.new(signed)
store = OpenSSL::X509::Store.new
p7_signed.verify(nil, store, nil, OpenSSL::PKCS7::NOVERIFY)
unsigned = p7_signed.data
# The tries to decrypt the data
OpenSSL::PKCS7.new(unsigned).decrypt(recipient_key, recipient_cert)
# => ArgumentError: Could not parse the PKCS7: nested asn1 error
为什么从
p7_signed
中提取的数据与crypted
中的数据不匹配?当我检查这两个字符时,我发现 unsigned
到处包含一些 \r
字符,而 crypted
没有。对此我能做什么?
(我在 Linux 上执行此操作,以防出现 CRLF 与 LF 的问题。)
您应该向
PKCS7_BINARY
提供 PKCS7.sign()
标志,可能以 OpenSSL::PKCS7::BINARY
形式提供。我根本不了解 Ruby,但阅读 ruby-doc.org 上的 docs 和 openssl 手册页 让我相信这就是问题所在。
来自 PKCS7 的 openssl 手册页(我做了一些小修正):
通常提供的内容会被翻译成 MIME 规范格式 (根据 S/MIME 规范的要求),但如果 PKCS7_BINARY 设置为 no 发生翻译。如果提供的数据是,则应使用此选项 以二进制格式保存,否则翻译会损坏它。
由于您对
OpenSSL::PKCS7.sign(...)
的输入是来自 OpenSSL::PKCS7.encrypt(...)
的 DER 编码输出,因此这本质上是二进制格式而不是文本。