openssl cms -verify 不适用于外部证书
openssl cms -verify doesn't work with external certificate
我研究了几天,终于想出了一个简单的测试用例。我需要签署并验证 SMIME/CMS 格式文件的签名,该文件不得包含证书。
签名工作正常,但只有当证书嵌入到签名文件中并且允许 openssl 使用它时,验证才有效。如果我不包含证书或者如果我告诉 openssl 忽略它,验证将失败,即使我在这两种情况下都明确指定了签名者证书和 CA 证书。
我有以下文件:
ca-crt.pem
– CA 证书
server-crt.pem
– 我用于签名的证书
server-key.pem
– 服务器的私钥
sample.xml
– 我要签名的示例文件
第一步:生成签名文件:
$ 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
。
第 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
.
我正在调查的问题是更大背景的一部分,事实证明我在这个特定测试用例中遇到的问题相当愚蠢:我使用了错误的参数来指示签名证书。验证时不应该使用 -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
我通常会完全删除这个问题,但也许将来有人会发现它有用。
我研究了几天,终于想出了一个简单的测试用例。我需要签署并验证 SMIME/CMS 格式文件的签名,该文件不得包含证书。
签名工作正常,但只有当证书嵌入到签名文件中并且允许 openssl 使用它时,验证才有效。如果我不包含证书或者如果我告诉 openssl 忽略它,验证将失败,即使我在这两种情况下都明确指定了签名者证书和 CA 证书。
我有以下文件:
ca-crt.pem
– CA 证书server-crt.pem
– 我用于签名的证书server-key.pem
– 服务器的私钥sample.xml
– 我要签名的示例文件
第一步:生成签名文件:
$ 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
。
第 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
.
我正在调查的问题是更大背景的一部分,事实证明我在这个特定测试用例中遇到的问题相当愚蠢:我使用了错误的参数来指示签名证书。验证时不应该使用 -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
我通常会完全删除这个问题,但也许将来有人会发现它有用。