openssl cms -verify 不适用于外部证书

Bog*_*scu 1 openssl cryptography signing smime

我已经研究了几天,终于想出了一个简单的测试用例。我需要签署并验证 SMIME/CMS 格式文件的签名,该文件不得包含证书。

\n\n

签名工作正常,但只有当证书嵌入到签名文件中并且允许 openssl 使用它时,验证才有效。如果我不包含证书或者告诉 openssl 忽略它,验证将失败,即使我在两种情况下都明确指定了签名者证书和 CA 证书。

\n\n

我有以下文件:

\n\n
    \n
  • ca-crt.pem\xe2\x80\x93 CA 证书
  • \n
  • server-crt.pem\xe2\x80\x93 我用于签名的证书
  • \n
  • server-key.pem\xe2\x80\x93 服务器的私钥
  • \n
  • sample.xml\xe2\x80\x93 我要签名的示例文件
  • \n
\n\n

步骤1:生成签名文件:

\n\n
$ openssl cms -sign -signer server-crt.pem -inkey server-key.pem -nodetach -md sha256 -in sample.xml -outform der -out sample.cms-der -noattr\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,我没有要求 openssl 排除证书。在最终版本中,我还必须添加-nocerts,但现在如果我们保留它,测试会更容易。

\n\n

步骤 2:使用嵌入证书验证签名

\n\n

好的,现在我们在sample.cms-der\xe2\x80\x93 中有签名文件,让我们首先使用签名文件中包含的证书来验证它:

\n\n
$ openssl cms -verify -CAfile ca-crt.pem -inform der -signer server-crt.pem -in sample.cms-der\nVerification successful\n
Run Code Online (Sandbox Code Playgroud)\n\n

步骤 3 Alpha:验证签名,忽略嵌入证书

\n\n

现在让我们要求 openssl 忽略嵌入在签名文件 \xe2\x80\x93 中的证书我使用完全相同的命令行,只是我-nointern在末尾添加了选项:

\n\n
$ openssl cms -verify -CAfile ca-crt.pem -inform der -signer server-crt.pem -in sample.cms-der -nointern\nVerification failure\n14712:error:2E09D08A:CMS routines:CMS_verify:signer certificate not found:.\\crypto\\cms\\cms_smime.c:333:\n
Run Code Online (Sandbox Code Playgroud)\n\n

当然,在这种情况下,我仍然可以验证签名,因为证书包含在 \xe2\x80\x93 中,但如果我使用该选项生成签名文件-nocerts,无论我是否使用验证,我最终都会遇到失败情况-nointern

\n\n

步骤 3 Beta:SMIME 代替 CMS

\n\n

我还尝试使用 smime 而不是 cms,有趣的是,虽然错误消息是相同的,但错误有不同的错误号,并且它来自源代码中的不同部分:

\n\n
$ openssl smime -verify -CAfile ca-crt.pem -inform der -signer server-crt.pem -in sample.cms-der -nointern\nVerification failure\n13580:error:2107C080:PKCS7 routines:PKCS7_get0_signers:signer certificate not found:.\\crypto\\pkcs7\\pk7_smime.c:466:\n
Run Code Online (Sandbox Code Playgroud)\n\n

我使用的 openssl 版本是OpenSSL 1.0.2n 7 Dec 2017.

\n

Bog*_*scu 5

我正在调查的问题是更大上下文的一部分,事实证明我在这个特定测试用例中遇到的问题相当愚蠢:我使用了错误的参数来指示签名证书。验证时不应该使用-signer来指示签名证书,但是-certfile

$ openssl cms -verify -CAfile ca-crt.pem -inform der -certfile server-crt.pem -in sample.cms-der -nointern
Verification successful
Run Code Online (Sandbox Code Playgroud)

它也适用于 SMIME:

$ openssl smime -verify -CAfile ca-crt.pem -inform der -certfile server-crt.pem -in sample.cms-der -nointern
Verification successful
Run Code Online (Sandbox Code Playgroud)

我通常会完全删除这个问题,但也许将来有人会发现这很有用。