【问题标题】:Get signing chain from CMSSignedData从 CMSSignedData 获取签名链
【发布时间】:2017-10-17 00:49:13
【问题描述】:

如何从CMSSignedData (BouncyCastle) 获取签名链,以通过签名链商店验证它?

Certificate[] storeCertChain = store.getCertificateChain(alias)

难道没有一个命令或类似的东西我可以得到数据的签名链吗?或者从签名链中获取证书?

【问题讨论】:

    标签: java bouncycastle sign verify chain


    【解决方案1】:

    用于签名的证书链可能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 集合内。

    如果链不存在,您将不得不在其他地方获取它。

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

    【讨论】:

      猜你喜欢
      • 2017-10-15
      • 1970-01-01
      • 2012-11-11
      • 2020-11-19
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      • 2015-10-27
      • 2016-07-08
      相关资源
      最近更新 更多