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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:17:04  来源:igfitidea点击:

XML Signature Validation

javaxmlx509

提问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

You get the X509 key from the embedded X509 certificate.

您可以从嵌入式 X509 证书中获取 X509 密钥。

UPDATE:

更新:

doing a google search for "xml signature x509certificate" turned up this page, which would seem to give you all the answers you need.

在谷歌上搜索“xml 签名 x509certificate”,出现了这个页面,它似乎给了你所有你需要的答案。

回答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();