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

时间:2014-08-06 14:09:28

标签: java pkcs#7

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

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

我看到的示例需要单独公钥来验证签名。是否可能需要公钥浮动带签名,某些工具会自动识别并验证数据? 如果是,我无法找到任何将验证此签名的Java API。

1 个答案:

答案 0 :(得分:2)

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

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

XML签名在XMLD Sig保护伞标准化,在此形式化:http://www.w3.org/TR/xmldsig-core/。 Oracle JDK使用XMLSignatureFactory基类附带参考实现(源自标准的Apache实现)。

但是,PKCS7不是用作XML DSig的一部分,所以你可能不得不“自己动手”(if中的一小部分),除非有一个我不知道的协议。 / p>

尽管如此,确实PKCS7(在某些情况下由CMS取代)是一种标准的加密格式,允许签名任意内容。该结构足够灵活,可以显着地保存:要签名的内容(可以嵌入或不嵌入),签名和相关的算法标识符,以及链接到签名的X509材料(例如证书和公钥,证书撤销列表。 ..)。

尽管Oracle JDK在sun.security.pkcs包下进行,但Java语言并未提供我所知的PKCS7处理的通用实现。

用于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