java - 签名验证(格式为 PKCS#7)

标签 java pkcs#7

我在 XML 中有以下内容 1. tag :这里的签名是PKCS#7格式的,这是国际标准。签名包括签名者的公钥证书(作为 PKCS#7 包的一部分)以及加密的数据散列。 2. tag:原始数据就在这个tag里。

我不明白如何验证签名。客户说“任何可以读取 PKCS#7 签名的 API/工具都可以为您提供公钥。”

我看到的示例需要单独的公钥来验证签名。是否有可能需要带有签名的公钥 float 并且某些工具会自动识别它并验证数据? 如果是,我找不到任何可以验证此签名的 java API。

最佳答案

作为序言,密码学的第一条规则:不要自己动手,在其记录的用例中使用经过验证的工具来执行操作。

所以我首先检查您的 XML 文档是否确实使用标准进行了签名(我不知道基于 PKCS7 的 XML 签名格式,但我当然不知道一切)。如果是这样,我会找到一个支持这种特定格式的库。

XML 签名是沿着 XMLD Sig 框架进行标准化的,在这里正式化:http://www.w3.org/TR/xmldsig-core/ 。 Oracle JDK 附带了一个引用实现(源自标准的 Apache 实现),使用 XMLSignatureFactory 基类。

不过,PKCS7 不用作 XML DSig 的一部分,因此您最终可能必须“自己做”(if 的一小部分),除非存在我不知道的协议(protocol)。

也就是说,PKCS7(在某些情况下被 CMS 取代)确实是一种标准加密格式,允许对任意内容进行签名。该结构足够灵活,可以显着地容纳:要签名的内容(可以嵌入或不嵌入)、签名和关联的算法标识符,加上链接到签名的 X509 Material (例如证书和公钥、证书吊销列表)。 ..).

据我所知,Java 语言没有提供 PKCS7 处理的通用实现,尽管 Oracle JDK 在 sun.security.pkcs 包下提供了这种实现。

在 Java 中进行 PKCS7 处理的一个流行的通用库是 BouncyCaSTLe。我对此比较熟悉,所以我就讲一下这个。

您可以在此处找到使用示例: http://i-proving.com/2007/09/21/pkcs7-signatures-using-bouncy-castle/

当您下载源代码时,Bouncy CaSTLe 有一个相当好的示例包,还有 Javadoc。因此您可以查看该 API 的最新使用情况。检查例如: https://www.bouncycastle.org/docs/pkixdocs1.5on/org/bouncycastle/cms/CMSSignedData.html ,转载于此以方便引用

CMSSignedData           s = new CMSSignedData(inputStream);
Store                   certStore = s.getCertificates(); // This is where you access embedded certificates
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();

  if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)))
  {
      verified++;
  } 
}

但请记住,检查签名的有效性是第一步,第二步是验证签名证书确实值得信赖。此处提供了一个示例:

Verifying PKCS#7 certificates in Java

关于java - 签名验证(格式为 PKCS#7),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25162605/

相关文章:

java - 使用FileOutputStream下载多个文件

java - JSR223 Javascript 中的回调,Oracle JRE 1.6 和 OpenJDK 1.6 之间的区别(安装在 Debian 上)

java - Android线程完成通知

php - 如何使用 PHP 从 PDF 中检索数字签名信息?

c++ - gcrypt 是针对哪个版本的 PKCS#1 规范实现的?

加密 - PKCS5/7 填充竞争条件?

php - 如何从 AES 加密字符串中添加/删除 PKCS7 填充?

java - 我必须将 json 文件放在哪里才能在 Java 中使用?

java - 尝试在加载 WebView URL 时在 Android Studio 2.3.3 中实现启动画面图像