1

我有一个问题,我不知道如何解决。我的应用程序收到一个(据说)签名的 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>

我在互联网上找到的所有要验证的东西都需要公钥。但我没有。我只有 DigestValue。您知道是否可以仅使用 DiggestValue 进行验证?

这是我到目前为止所拥有的。问题是从哪里获取 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));

提前致谢。

4

3 回答 3

6

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

更新:

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

于 2013-05-15T04:05:32.960 回答
4

您可能需要在 DocumentBuilderFactory 上调用 setNamespaceAware(true),否则会抛出以下异常:

Document implementation must support DOM Level 2 and be namespace aware
于 2016-11-14T09:47:21.313 回答
2

证书本身包含公钥:

CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(Base64.getDecoder().decode(certificateStringFromXml));
X509Certificate cert = (X509Certificate)certFactory.generateCertificate(in);
PublicKey pk = cert.getPublicKey();
于 2017-11-08T16:34:53.323 回答