验证未编组对象的数字签名失败

问题描述 投票:0回答:0

我按照本指南签署和验证 XML 消息https://www.oracle.com/technical-resources/articles/java/dig-signature-api.html。验证使用生成的文档。这种方法工作正常。

然而,在我们的用例中,我们将在我们的端点接收到一个签名的 XML 消息,因此我们将这个对象转换成一个文档:

public boolean validate(SignXml<?> xml) throws MarshalException, XMLSignatureException {

    boolean status;
    try {
        status = validate(convertToDocument(xml));

    } catch (ParserConfigurationException | JAXBException | IOException | SAXException ex) {
        throw new XMLSignatureException(ex);
    }

    return status;
}

protected Document convertToDocument(SignXml<?> xml) throws ParserConfigurationException, JAXBException, IOException, SAXException {

    DocumentBuilderFactory dbf = getDocumentBuilderFactory();
    dbf.setNamespaceAware(true);

    return dbf.newDocumentBuilder().parse(getStreamSource(xml));
}

private StreamSource getStreamSource(Document node) throws TransformerException {

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    Result outputTarget = new StreamResult(outputStream);
    Transformer t = getTransformer();
    t.transform(new DOMSource(node), outputTarget);

    return new StreamSource(new InputStreamReader(new ByteArrayInputStream(outputStream.toByteArray()), StandardCharsets.UTF_8));
}

public boolean validate(Document doc) throws MarshalException, XMLSignatureException, IOException {

    try {
        System.out.println("validate: " + getStringFromDocument(doc));
    } catch (TransformerException e) {
        throw new RuntimeException(e);
    }

    // Find Signature element
    NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
    if (nl.getLength() == 0) {
        throw new SignatureNotFoundException("Signature element not found");
    }

    // Create a DOMValidateContext and specify a KeySelector and document context
    DOMValidateContext valContext = new DOMValidateContext(new X509KeySelector(), nl.item(0));
    valContext.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.TRUE);
    valContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);

    // Unmarshal the signature
    XMLSignature signature = signatureFactory.unmarshalXMLSignature(valContext);

    // Validate the signature
    boolean coreValidity = signature.validate(valContext);

    if (!coreValidity) {
        LOGGER.error("Signature failed core validation");

        boolean sv = signature.getSignatureValue().validate(valContext);
        LOGGER.error("Signature validation status: {}", sv);
        if (!sv) {
            // Check the validation status of each Reference.
            for (Reference ref : signature.getSignedInfo().getReferences()) {
                boolean isRefValid = ref.validate(valContext);
                LOGGER.debug("Reference '{}' {}", ref.getURI(), isRefValid ? "valid" : "invalid");
            }

        } else {
            LOGGER.debug("Signature passed core validation");
        }
    }

    return coreValidity;
}

但是失败了。在调试模式下,我发现生成的摘要与解码值不同:

似乎是 JAXB 解组的问题。是什么导致了这个问题?

jaxb digital-signature code-signing unmarshalling
© www.soinside.com 2019 - 2024. All rights reserved.