如何从GetSqlDecimal
(BouncyCastle)获取签名链以通过签名连锁店进行验证?
CMSSignedData
是否有命令或类似的东西我可以获得数据的签名链?或者从签名链中获取证书?
答案 0 :(得分:2)
用于签署的证书链可能位于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
字段描述为:
证书是证书的集合。它的目的是 证书集足以包含证书 来自公认的" root"的路径或者"顶级认证 权威" 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
集合将包含签署者证书,{strong>如果它出现在certificates
字段中。然后,您可以使用它来验证签名,就像您正在执行in your other question一样。
要检查整个链是否在CMS结构中,您可以获取Store
中的所有证书并检查它们是否在那里。
要将所有内容都放在Store
中,您可以使用与使用here类似的代码:
Collection<X509CertificateHolder> allCerts = store.getMatches(null);
在我使用的版本( BouncyCastle 1.56 )中,传递null
会返回商店中的所有证书。然后,您可以检查链是否在allCerts
集合中。
如果没有链条,你必须把它拿到别的地方。