java - 从 CMSSignedData 获取签名链

标签 java bouncycastle sign verify chain

如何从 CMSSignedData (BouncyCaSTLe) 获取签名链以通过签名链存储对其进行验证?

Certificate[] storeCertChain = store.getCertificateChain(alias)

没有命令或类似的东西我可以获取数据的签名链吗?或者从它那里获取证书并从签名链那里获取证书?

最佳答案

用于签名的证书链可能位于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 is a collection of certificates. It is intended that the set of certificates be sufficient to contain certification paths from a recognized "root" or "top-level certification authority" to all of the signers in the signerInfos field. There may be more certificates than necessary, and there may be certificates sufficient to contain certification paths from two or more independent top-level certification authorities. There may also be fewer certificates than necessary, if it is expected that recipients have an alternate means of obtaining necessary certificates (e.g., from a previous set of certificates). The signer's certificate MAY be included.

请注意,certificates 字段是可选的,即使存在,其所有内容也是可选的。因此,该字段可能包含证书链,但不能保证。

如果此字段存在,您可以使用 BouncyCaSTLe 获取它(我使用的是 1.56 版本):

import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.util.Store;

CMSSignedData sigData = ...
Store store = sigData.getCertificates();

当没有证书时,我不确定 getCertificates() 是否返回 null 或空的 Store (我认为它可能根据实现情况而有所不同)。

如果Storenull,您可以检查签名者的证书是否存在:

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 )
  • 如果不可能,您必须下载链或向签名者获取证书

关于java - 从 CMSSignedData 获取签名链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44026852/

相关文章:

java - "Every object being available for locking"是反模式吗?

java - TextRecognizer.isOperational() API 始终返回 false

java - 尽管套接字从未手动关闭,但由于SocketException而导致DTLS握手失败

java - 如何在 java 中使用 bouncycaSTLe 将 PrivateKeyUsage 扩展添加到证书?

installation - bundle 无效负载原因 : 0x80070570

java - POI 单元格颜色和宽度

java - 找不到 Media type=text/plain、type=class java.util.ArrayList、genericType=java.util.List<models.Person> 的 MessageBodyWriter

java - 如何使用 bouncy caSTLe 库对 IP 地址进行编码?

c# - 电子 token 证书的签名和验证

c# - 签署 Windows 应用程序