如何从 CMSSignedData
(BouncyCaSTLe) 获取签名链以通过签名链存储对其进行验证?
Certificate[] storeCertChain = store.getCertificateChain(alias)
没有命令或类似的东西我可以获取数据的签名链吗?或者从它那里获取证书并从签名链那里获取证书?
最佳答案
用于签名的证书链可能位于CMSSignedData
中,但这不是强制性的。
根据RFC 3852 ,CMS SignedData 具有 following structure (described in section 5.1) :
SignedData ::= SEQUENCE {
version CMSVersion,
digestAlgorithms DigestAlgorithmIdentifiers,
encapContentInfo EncapsulatedContentInfo,
certificates [0] IMPLICIT CertificateSet OPTIONAL,
crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
signerInfos SignerInfos }
certificates
字段描述为:
certificates is a collection of certificates. It is intended that the set of certificates be sufficient to contain certification paths from a recognized "root" or "top-level certification authority" to all of the signers in the signerInfos field. There may be more certificates than necessary, and there may be certificates sufficient to contain certification paths from two or more independent top-level certification authorities. There may also be fewer certificates than necessary, if it is expected that recipients have an alternate means of obtaining necessary certificates (e.g., from a previous set of certificates). The signer's certificate MAY be included.
请注意,certificates
字段是可选的,即使存在,其所有内容也是可选的。因此,该字段可能包含证书链,但不能保证。
如果此字段存在,您可以使用 BouncyCaSTLe 获取它(我使用的是 1.56 版本):
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.util.Store;
CMSSignedData sigData = ...
Store store = sigData.getCertificates();
当没有证书时,我不确定 getCertificates()
是否返回 null
或空的 Store
(我认为它可能根据实现情况而有所不同)。
如果Store
不null
,您可以检查签名者的证书是否存在:
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
SignerInformationStore signers = sigData.getSignerInfos();
Collection<SignerInformation> c = signers.getSigners();
for (SignerInformation signer : c) {
// this collection will contain the signer certificate, if present
Collection signerCol = store.getMatches(signer.getSID());
}
signerCol
集合将包含签名者证书,如果它出现在certificates
字段中。然后您可以使用它来验证签名,就像您所做的那样 in your other question .
要检查整个链是否在 CMS 结构中,您可以获取 Store
中的所有证书并检查它们是否存在。
要获取 Store
中的所有内容,您可以使用类似于使用 here 的代码。 :
Collection<X509CertificateHolder> allCerts = store.getMatches(null);
在我使用的版本 (BouncyCaSTLe 1.56) 中,传递 null
返回存储中的所有证书。然后,您可以检查该链是否位于 allCerts
集合内。
如果链条不存在,您必须从其他地方获取它。
- 如果您有签名者(最终实体)证书,您可以使用权威信息访问来尝试(检查 this answer )
- 如果不可能,您必须下载链或向签名者获取证书
关于java - 从 CMSSignedData 获取签名链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44026852/