【发布时间】:2017-10-17 00:49:13
【问题描述】:
如何从CMSSignedData (BouncyCastle) 获取签名链,以通过签名链商店验证它?
Certificate[] storeCertChain = store.getCertificateChain(alias)
难道没有一个命令或类似的东西我可以得到数据的签名链吗?或者从签名链中获取证书?
【问题讨论】:
标签: java bouncycastle sign verify chain
如何从CMSSignedData (BouncyCastle) 获取签名链,以通过签名链商店验证它?
Certificate[] storeCertChain = store.getCertificateChain(alias)
难道没有一个命令或类似的东西我可以得到数据的签名链吗?或者从签名链中获取证书?
【问题讨论】:
标签: java bouncycastle sign verify chain
用于签名的证书链可能在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 是证书的集合。其目的是 证书集足以包含认证 来自公认的“根”或“顶级认证”的路径 授权”到 signerInfos 字段中的所有签名者。那里 可能证书比必要的多,并且可能有 证书足以包含来自两个或 更独立的顶级认证机构。 可能会有 也比必要的证书少,如果预计 接受者有另一种方式来获得必要的 证书(例如,来自以前的一组证书)。这 可能包含签名者的证书。
注意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 集合内。
如果链不存在,您将不得不在其他地方获取它。
【讨论】: