gpt4 book ai didi

java - 结合验证 PKCS#7 签名所需的所有任务

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:09:50 25 4
gpt4 key购买 nike

我已经为这个问题苦苦思索了大约 20 个小时,我可能遗漏了一些简单的东西。但是,我已经到了我认为需要帮助的地步。我已经阅读了数十种关于如何解决问题不同部分的解释,但我无法弄清楚如何将它们组合在一起。

我有一个 DER 编码的分离 PKCS#7 数字签名。签名符合 RFC 3852(加密消息语法)。对于我的项目,我需要逐步完成验证签名所需的每个步骤,并能够判断验证失败的步骤。我在 Java 中使用 BouncyCaSTLe。

据我了解,验证数字签名需要六个基本步骤

  1. 验证根证书是受信任的证书
  2. 验证从根证书到签名证书的证书链
  3. 验证签名者的姓名是否符合您的预期
  4. 验证证书没有过期
  5. 验证证书没有出现在 CRL 上(为简单起见,假设 CRL 已在本地下载)
  6. 验证签名中的摘要是否与文档的摘要匹配

编辑:一些评论要求将 OSCP 检查添加到列表中。

在 BouncyCaSTLe 测试代码中,我能够找到以下示例。它似乎完成了 2/6,但是并不清楚它是否完成了任何任务。如果有人能为我指出其余任务的正确方向,将不胜感激。

CMSSignedData s = ...
byte[] contentDigest = ...

Store certStore = s.getCertificates();
Store crlStore = s.getCRLs();
SignerInformationStore signers = s.getSignerInfos();

Collection c = signers.getSigners();
Iterator it = c.iterator();

while (it.hasNext())
{
SignerInformation signer = (SignerInformation)it.next();
Collection certCollection = certStore.getMatches(signer.getSID());

Iterator certIt = certCollection.iterator();
X509CertificateHolder cert = (X509CertificateHolder)certIt.next();

assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert)));

if (contentDigest != null)
{
assertTrue(MessageDigest.isEqual(contentDigest, signer.getContentDigest()));
}
}

Collection certColl = certStore.getMatches(null);
Collection crlColl = crlStore.getMatches(null);

assertEquals(certColl.size(), s.getCertificates().getMatches(null).size());
assertEquals(crlColl.size(), s.getCRLs().getMatches(null).size());

最佳答案

CMS 签名数据验证中最复杂的是 X.509 验证部分。对于签名数据中的每个签名者,步骤如下:

<强>1。找到签署者证书

SignerInformation signerInfo = (SignerInformation)it.next();
Collection certCollection = certStore.getMatches(signerInfo.getSID());
Iterator certIt = certCollection.iterator();
X509CertificateHolder signerCertificateHolder = (X509CertificateHolder)certIt.next();

我假设这里只有一个匹配的证书。

<强>2。查找从签署者证书到受信任的根证书的证书链

在这里,您要检查 Store 中的证书以找到证书链。使用主题 DN/发行者 DN 和主题 key 标识符/授权 key 标识符匹配来构建该链。

<强>3。验证链

此步骤递归验证链中的每个证书。对于每个证书,从直接在根证书下的证书开始您需要检查:

  1. 带有颁发者公钥的证书签名
  2. 证书的有效期
  3. 证书的吊销状态

希望您可以在第 2 步和第 3 步中使用内置的 PKIX 证书路径构建器和验证机制:

KeyStore trustAnchors = getTrustAnchors();
X509CertSelector target = new X509CertSelector();
target.setCertificate(signerCertificate);
PKIXBuilderParameters params = new PKIXBuilderParameters(anchors, target);
CertStoreParameters additionalCerts = new CollectionCertStoreParameters(allOtherCerts)
params.addCertStore(CertStore.getInstance("Collection", additionalCerts));
CertStoreParameters revocationObjects = new CollectionCertStoreParameters(allCRLs);
params.addCertStore(CertStore.getInstance("Collection", revocationObjects));
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
PKIXCertPathBuilderResult r = (PKIXCertPathBuilderResult) builder.build(params);
/* if the build method returns without exception, the certificate chain is valid */

为了可读性,我省略了对象在 java(x).crypto 和 BouncycaSTLe 类型之间的转换。

<强>4。使用公钥验证 SignerInfo 签名

JcaSimpleSignerInfoVerifierBuilder builder = new JcaSimpleSignerInfoVerifierBuilder();
SignerInformationVerifier verifier = builder.build(signerCertificateHolder);
assertTrue(signerInfo.verify(verifier));

<强>5。验证文档摘要是否与签名摘要匹配

byte[] contentDigest = computeDigest(originalDoc, signerInfo.getDigestAlgOID());
assertArrayEquals(contentDigest, signer.getContentDigest());

关于java - 结合验证 PKCS#7 签名所需的所有任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20853157/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com