我在XML中有以下内容 1.标签:签名是PKCS#7格式,这是一个国际标准。签名包括签名者的公钥证书,作为PKCS#7包的一部分,以及加密的数据哈希。 2. tag:原始数据在此标记中。
我不明白如何验证签名。客户说“任何可以读取PKCS#7签名的API /工具都可以为您提供公钥”。
我看到的示例需要单独公钥来验证签名。是否可能需要公钥浮动带签名,某些工具会自动识别并验证数据? 如果是,我无法找到任何将验证此签名的Java API。
答案 0 :(得分:2)
作为序言,密码学的第一条规则:不要自己动手,在其记录的用例中使用经过验证的工具来执行操作。
所以我首先检查你的XML文档是否确实是使用标准签名的(我不知道基于PKCS7的XML签名格式,但是,我肯定不知道所有内容)。如果是这样,我会找到一个支持这种特定格式的库。
XML签名在XMLD Sig
保护伞标准化,在此形式化:http://www.w3.org/TR/xmldsig-core/。 Oracle JDK使用XMLSignatureFactory
基类附带参考实现(源自标准的Apache实现)。
尽管如此,确实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++;
}
}
请记住,检查签名的有效性是一步,第二步是验证签名证书确实值得信赖。这里有一个例子: