java XML 签名验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16549936/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
XML Signature Validation
提问by Augusto
I have a problem that I can't figure out how to solve. My application receives a (supposedly) signed XML and I have to validate if it is right. Here's the signature part of what a receive in the XML
我有一个问题,我不知道如何解决。我的应用程序收到一个(据说)签名的 XML,我必须验证它是否正确。这是 XML 中接收内容的签名部分
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="35121103220612000188550010000000131000009300">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>uLZ/66r6OoNLpj5v4cIsrv5zmyc=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>encoded</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>encoded</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
Everything I found on internet to validate needs the public key. But I don't have it. I have only the DigestValue. Do you know if its possible to validate using only the DiggestValue?
我在互联网上找到的所有需要验证的东西都需要公钥。但我没有。我只有 DigestValue。您知道是否可以仅使用 DigestValue 进行验证?
Here's what I have so far. The problem is where to get the key for X509KeySelector
这是我到目前为止所拥有的。问题是从哪里获取 X509KeySelector 的密钥
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse("/home/test.xml");
Node nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature").item(0);
DOMValidateContext valContext = new DOMValidateContext(new X509KeySelector(publicKey), nl);
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
XMLSignature signature = factory.unmarshalXMLSignature(valContext);
System.out.println(signature.validate(valContext));
Thanks in advance.
提前致谢。
回答by jtahlborn
回答by digz6666
You may need to call setNamespaceAware(true) on your DocumentBuilderFactory, otherwise it will throw following exception:
您可能需要在 DocumentBuilderFactory 上调用 setNamespaceAware(true),否则会抛出以下异常:
Document implementation must support DOM Level 2 and be namespace aware
回答by Zoltan
The certificate itself contains the public key:
证书本身包含公钥:
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(Base64.getDecoder().decode(certificateStringFromXml));
X509Certificate cert = (X509Certificate)certFactory.generateCertificate(in);
PublicKey pk = cert.getPublicKey();