我已经调查了几天,最后我想出了一个简单的测试用例。我需要签署并验证SMIME / CMS格式文件的签名,该文件不得包含证书。
签名工作正常,但验证仅在证书嵌入签名文件中时才有效,并且允许openssl使用它。如果我不包含证书或者如果我告诉openssl忽略它,则验证失败,即使我在两种情况下都明确指定了签名者证书和CA证书。
我有以下文件:
ca-crt.pem
- CA证书server-crt.pem
- 我用于签名的证书server-key.pem
- 服务器的私钥sample.xml
- 我要签名的示例文件第1步:生成签名文件:
$ openssl cms -sign -signer server-crt.pem -inkey server-key.pem -nodetach -md sha256 -in sample.xml -outform der -out sample.cms-der -noattr
注意我没有要求openssl排除证书。在最终版本中,我还必须添加-nocerts
,但是现在我们更容易测试是否将其保留。
步骤2:使用嵌入式证书验证签名
好的,现在我们在sample.cms-der
中有了签名文件 - 我们首先使用签名文件中包含的证书对其进行验证:
$ openssl cms -verify -CAfile ca-crt.pem -inform der -signer server-crt.pem -in sample.cms-der
Verification successful
步骤3 Alpha:验证签名忽略嵌入证书
现在让我们让openssl忽略签名文件中嵌入的证书 - 我使用完全相同的命令行,除了我在最后添加-nointern
选项:
$ openssl cms -verify -CAfile ca-crt.pem -inform der -signer server-crt.pem -in sample.cms-der -nointern
Verification failure
14712:error:2E09D08A:CMS routines:CMS_verify:signer certificate not found:.\crypto\cms\cms_smime.c:333:
当然,在这种情况下,我仍然可以验证签名,因为证书已包含在内 - 但如果我使用-nocerts
选项生成签名文件,我最终会遇到故障情况,无论我是否验证使用-nointern
或不。{/ p>
第3步测试:SMIME而不是CMS
我也尝试使用smime而不是cms,有趣的是,虽然错误信息是相同的,但错误的错误编号不同,它来自源代码中的不同部分:
$ openssl smime -verify -CAfile ca-crt.pem -inform der -signer server-crt.pem -in sample.cms-der -nointern
Verification failure
13580:error:2107C080:PKCS7 routines:PKCS7_get0_signers:signer certificate not found:.\crypto\pkcs7\pk7_smime.c:466:
我正在使用的openssl版本是OpenSSL 1.0.2n 7 Dec 2017
。
答案 0 :(得分:1)
我正在调查的问题是更大的上下文的一部分,并且结果发现我在这个特定的测试用例中遇到的问题相当愚蠢:我使用了错误的参数来指示签名证书。在验证时,不应使用-signer
来指示签名证书,而是-certfile
:
$ openssl cms -verify -CAfile ca-crt.pem -inform der -certfile server-crt.pem -in sample.cms-der -nointern
Verification successful
它也适用于SMIME:
$ openssl smime -verify -CAfile ca-crt.pem -inform der -certfile server-crt.pem -in sample.cms-der -nointern
Verification successful
我通常会完全删除这个问题,但也许有人会在将来发现它很有用。