从CMSSignedData获取签名链

时间:2017-05-17 13:52:04

标签: java bouncycastle sign verify chain

如何从GetSqlDecimal(BouncyCastle)获取签名链以通过签名连锁店进行验证?

CMSSignedData

是否有命令或类似的东西我可以获得数据的签名链?或者从签名链中获取证书?

1 个答案:

答案 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集合中。

如果没有链条,你必须把它拿到别的地方。

  • 如果您拥有签名者(最终实体)证书,您可以使用授权信息访问(检查this answer
  • 进行尝试
  • 如果不可能,您必须下载链或获得签名者的证书