如何从CMSSignedData (BouncyCastle)获得签名链,以便通过签名连锁店验证它?
Certificate[] storeCertChain = store.getCertificateChain(alias)没有命令或类似的东西吗?我可以得到数据的签名链吗?还是从它那里从签名链那里得到证书?
发布于 2017-05-18 12:51:00
用于签名的证书链可能在CMSSignedData中,但不是强制性的。
根据RFC 3852的说法,CMS SignedData有以下结构(见5.1节)
SignedData ::= SEQUENCE {
version CMSVersion,
digestAlgorithms DigestAlgorithmIdentifiers,
encapContentInfo EncapsulatedContentInfo,
certificates [0] IMPLICIT CertificateSet OPTIONAL,
crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
signerInfos SignerInfos }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字段中,则为。然后,您可以使用它来验证签名,就像您正在执行的在你的另一个问题一样。
要检查整个链是否在CMS结构中,您可以获取Store中的所有证书,并检查它们是否存在。要获取Store中的所有内容,可以使用与已使用的这里类似的代码
Collection<X509CertificateHolder> allCerts = store.getMatches(null);在我使用的版本(BouncyCastle 1.56)中,传递null将返回存储中的所有证书。然后,您可以检查链是否在allCerts集合中。
如果链不存在,你就得把它带到别处去。
https://stackoverflow.com/questions/44026852
复制相似问题