我获得了来自 OpenSSL 签名过程的 .tsr 响应。openssl ts -reply
有效。
openssl ts -reply -in b1.tsr -text
Using configuration from g:/progs/openssl/ssl/openssl.cnf
Status info:
Status: Granted.
Status description: unspecified
Failure info: unspecified
TST info:
Version: 1
Policy OID: 1.3.6.1.4.1.6449.2.1.1
Hash Algorithm: sha256
Message data:
0000 - 10 20 96 d8 03 ec ed 6e-03 56 3d d6 d6 a7 14 50 . .....n.V=....P
0010 - b0 a7 53 a9 34 4e b9 57-f7 e2 83 13 5e 0d df e0 ..S.4N.W....^...
Serial number: 0xA7ADC6135D0A39500F7C3B0C41578D8C2CB62B87
Time stamp: Jun 22 10:59:44 2019 GMT
Accuracy: unspecified
Ordering: no
Nonce: 0xD4154ECA4E9A0D06
TSA: DirName:/C=GB/ST=Greater Manchester/L=Salford/O=Sectigo Limited/CN=Sectigo RSA Time Stamping Signer #1
Extensions:
openssl ts -verify
失败。
openssl ts -verify -sha256 -digest "102096d803eced6e03563dd6d6a71450b0a753a9344eb957f7e283135e0ddfe0" -in b1.tsr -CAfile comodo.pem
Verification: FAILED
11928:error:2F06D064:time stamp routines:TS_VERIFY_CERT:certificate verify error:.\crypto\ts\ts_rsp_verify.c:264:Verify error:unable to get local issuer certificate
本地颁发者证书到底是怎么回事?我无法在“ts”命令中使用 -noverify。
答案1
为了构建一个完整的证书链以供 openssl 验证,您不仅需要根证书(您使用开关指定-CAfile
),还需要用于签署 TSResponse 的证书。
来自的手册页ts
:
-untrusted cert_file.pem
Set of additional untrusted certificates in PEM format which may be needed when building the certificate chain for the TSA's signing certificate. This
file must contain the TSA signing certificate and all intermediate CA certificates unless the response includes them. (Optional)
答案2
验证错误“无法获取本地颁发者证书”意味着 OpenSSL 无法在本地信任库中找到完整链的根(或锚点),或者不完整链的下一个链接(可能是也可能不是根/锚点)。
作为背景,由于您没有表明您对基于证书的验证的了解程度,因此ts -verify
基本上由四个部分组成:
检查令牌主体上的签名是否使用(声明的)签名者证书中的公钥进行验证,并且满足 RFC3161 施加的一些其他约束(必须只有一个 SignerInfo,并且必须使用包含 ESSCertId 的signedAttrs)。签名者的证书是否包含在时间戳响应中由 RFC3161 请求中的标志控制;如果不包含,则验证者/依赖者必须已经拥有它或通过其他方式获取它。
建立一个链(也称为路径),将声明的签名者的证书链接到至少一个受信任的 CA,由一个称为根证书或锚证书的 CA 证书表示,该证书在本地定义为受信任,通常存在于信任库中。RFC3161 响应可能包括链证书但这不是必需的;如果没有,验证者/依赖者必须已经拥有它/它们或通过其他方式获取它/它们。
通过检查每个证书的签名是否在下一个更高证书(即父证书)的公钥下进行验证,检查每个证书在签名时是否有效(有效且未过期),以及每个证书中的许多其他字段是否适合在链中使用来验证链;请参阅RFC5280 第 6 节。 验证应该包括检查链中的每个证书是否未被撤销(截至签名时),但 OpenSSL 默认不执行此部分;有几种选项可以执行几种撤销检查,但您没有使用其中任何一个。
最后,检查证书(链)是否适合此处的目的,即时间戳。对于 SSL/TLS 和 S/MIME 等其他证书使用情况,我们通常不仅需要检查证书是否在受信任 CA 的授权下合法颁发,还需要检查证书是否由到特定实体(网站、邮件服务器或个人,可可靠识别)。然而对于时间戳,我们通常不关心哪个TSA 发行了令牌,仅此而已一些有效的 TSA 确实如此,所以最后的检查只验证证书/链的 ExtendedKeyUsage 是否包含(标准化 OID,因此允许)时间戳。
综合起来(并且只有综合起来),这些才能证明我们拥有的数据实际上是由有效 TSA 颁发的时间戳令牌,并且没有被有意或无意地伪造或更改,因此是可以信任的。
对于 OpenSSL 命令行,根/锚点必须位于所使用的信任库中,该信任库由指定的-CAfile
和/或-CApath
默认的 CAfile 和/或 CApath(如果存在)组成,无论哪种情况,都是 PEM 格式;并且(虽然手册页不是很清楚)响应消息中没有的任何其他链证书必须任何一个位于信任库中或提供的文件中-untrusted
(必须是单个文件,但可以包含多个 PEM 格式的证书)。默认情况下,只有根证书(并且历史上只有根证书)被接受为链/路径锚点,但从-partial_chain
1.0.2 开始,可以使用选项接受信任库中的非根锚点。
显示内容ts -reply -text
不显示 CMS 级别,特别是其中提供了哪些证书。您可以看到所有内容,asn1parse -inform der [-i]
但必须手动解码。更方便的是,您可以提取 CMS SignedData 部分,即签名令牌,如下所示我的答案在这里然后按如下方式检查证书:
openssl ts -reply -in respfile -token_out -out tokenfile
openssl pkcs7 -inform der -in tokenfile -print_certs
# if desired/necessary, feed any or each of the PEM cert block(s)
# to openssl x509 -text -noout to get full details
我没有使用过这个 TSA,但根据众所周知的公共 TSA 证书和链应该公开记录的原则,crt.sh(也由 Comodo-now-Sectigo 运行)所知的唯一带有该主题的记录证书是https://crt.sh/?id=1437463789有一个已知父类Sectigo RSA Time Stamping CA
https://crt.sh/?id=1437089092其颁发者是USERTrust RSA Certification Authority
;该 CA 有四个证书(潜在父证书)列在https://crt.sh/?caid=1167-- 其中一个是 Microsoft codesigning,通常仅在时间戳用于 Microsoft Authenticode 代码签名时使用,其他三个都适用于一般用途,尽管唯一名为 Comodo 的版本相当新(仅在 3 个月前发布)。FWIW id=1437089092 中的 AIA 指向http://crt.usertrust.com/USERTrustRSAAddTrustCA.crt它提供来自 AddTrust 根的证书https://crt.sh/?id=4860286这是最古老的一张(发行于 2000 年,一年内到期)。
使用消息中的证书来确定您想要使用的根或锚点需要哪些附加链和锚点证书,并将其-CAfile
与您可能使用的文件中提供的内容进行比较-untrusted
。