java - 验证 XML 签名 JAVA

标签 java xml rsa xml-signature

是否可以验证以下 XML 文档:

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<DigestValue>DsP5NLca+plhp9tZvGwykfb2whQYt3CQ5sbsVd9Q9aE=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
LrfE0po3YPvVxB/m77iBWWiR07Ghiuhuj7tO2C2LKqZK2cLrAiidt+3tjbJ3m16quCFxfh7bmjRtJsGi7a3HKtK
qY4auqrjNB62AtYrxvm+7Qd/cRacom4e3M9uF9JD1zTfoGun9w4WDfDrDaoZ+ZwUgNtf6sTYO5Ctcj5sYcD0=
</SignatureValue>
<KeyInfo>
<KeyName>7D665C81ABBE1A7D0E525BFC171F04D276F07BF2</KeyName>
</KeyInfo>
</Signature>

问题是当我运行代码时,出现此错误

Exception in thread "main" javax.xml.crypto.dsig.XMLSignatureException: cannot find validation key
    at org.jcp.xml.dsig.internal.dom.DOMXMLSignature$DOMSignatureValue.validate(Unknown Source)
    at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.validate(Unknown Source)
    at paket.XmlValidator.validate(XmlValidator.java:28)
    at paket.Test.main(Test.java:43)
Caused by: javax.xml.crypto.KeySelectorException: No KeyValue element found!
    at paket.KeyValueKeySelector.select(KeyValueKeySelector.java:47)
    ... 4 more
javax.xml.crypto.KeySelectorException: No KeyValue element found!
    at paket.KeyValueKeySelector.select(KeyValueKeySelector.java:47)
    at org.jcp.xml.dsig.internal.dom.DOMXMLSignature$DOMSignatureValue.validate(Unknown Source)
    at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.validate(Unknown Source)
    at paket.XmlValidator.validate(XmlValidator.java:28)
    at paket.Test.main(Test.java:43)

我已使用相同的代码成功验证了以下 XML:

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>+uYi9GD7lNpk5+AZWjVylxm4PeKGXoFEalJPd44oMeg=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>Ov9TJmROGakTblMO8F2otx3YsmzY1N7tUEuJVauqP4EgePUtYpfMdiv1fKdZreeLyri7WRIOrxiq
mEJEWCmpzVKZypJ293y4STmRw4rfUgFQeaatj2AmK2q5zDaE9jzl6+HtiRgDykZpgx7DWC8MHydK
P8wnEHyn2ozYdqL0VCjRfk95zcm0jMknWmytippXf1bqufkhlOLdS46VGyvYM8ZAc742MN3QX1+I
SvNs1a+FNrgQwb0NaYLzX2hWOtFNo2ZparQXynfQy1jj6JHBRvmldLjHiI4nwYgtfEZL6Fgh/H6c
PSnM/Sd6hoh1B6zjhbIViqfaLKLkds/Et6WNYw==</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>xhbxdz2KP0/GwuoBuE2EfqoSUHj5nTZAC7c+UoUYtpqC8yRfe6BaFjdT/kWJNM8rZhJRawkh8qub
U4Iag0N1Cu8JNgOMXjeFJnVpa1HDijk9blQhLybGawh+TrC1v8D/9OGN5avkAjG/jpEFofOUpINp
Z2ThbhjgOzZV2kSa776nlwLhTLChf0iL5a78otVcDcuU8nmVkkhwFLbggbIRgdVFAk0bKFDYwWqw
kOmimDs2c7lLvu9n+X6IEFJLKt5YmKsBlhxx7LjvVih7vFc27+OtQpKw2EZjHPpmcP/qOEzESOCe
C8AHDrw3EWU5n1Bib8t8WteE5WPd2HbsJ86o3w==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>

这两个 XML 签名之间有什么区别,为什么它适用于第二个 XML 示例而不是第一个 ???

最佳答案

KeyValueKeySelector 在这里不会为您提供帮助,因为该签名不包含 KeyValue。 您必须扩展 KeySelector 并实现例如KeyNameKeySelector 将根据给定的 KeyName 在 KeyStore 中查找实际的 key 。如果您在该 keystore 中拥有该 key ,那么您就可以验证该签名。

这应该可以帮助您继续:http://jirablog.blogspot.no/2007/11/xml-signature-pouzit-nebo-ne.html

关于java - 验证 XML 签名 JAVA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12580062/

相关文章:

java - 如何使用 ascii 表将 char 转换为十进制?

python - 带有 lxml 子路径的 XPath 谓词?

python - 在python中解析旧的excel xml

javascript - 让用户下载经过处理的 SVG

python - 使用 Python 从 Azure Key Vault 解码 JsonWebKey

java - 了解 JMH 输出

java - 无法使用 apache common io 中的比较器解析方法排序

java - Azure 将 java Web App(java) 连接到 SQLDatabase

c# - 从私有(private)指数 (d)、公共(public)指数 (e) 和模数 (n) 计算素数 p 和 q

java - 为什么我使用 OpenSSL 和 Java 生成的 RSA-SHA256 签名不同?