0

我已经签署了一个 xml 文档并正在尝试验证签名。

我一直在阅读 XML API 中给出的示例代码,如下所示

检查验证后,它说核心验证失败签名验证失败,但参考有效性为真。

这些类型的验证有何不同?应该考虑什么来说明 xml 签名已被验证为真实或不真实

public class Validate {
public static void main(String[] args) throws Exception {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc =dbf.newDocumentBuilder().parse(new FileInputStream("C:\\ABC1.xml"));
    NodeList nl =doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
    DOMValidateContext valContext;
    for(int signature_count=0;signature_count<nl.getLength();signature_count++)
    {

    valContext= new DOMValidateContext(new KeyValueKeySelector(),nl.item(signature_count));
    XMLSignature signature = fac.unmarshalXMLSignature(valContext);
    boolean coreValidity = signature.validate(valContext);
    // Check core validation status
    if (coreValidity == false) {
        System.err.println("Signature failed core validation");
        boolean sv = signature.getSignatureValue().validate(valContext);
        System.out.println("signature validation status: " + sv);
        // check the validation status of each Reference
        Iterator i = signature.getSignedInfo().getReferences().iterator();
        for (int j = 0; i.hasNext(); j++) {
            boolean refValid =((Reference) i.next()).validate(valContext);
            System.out.println("ref[" + j + "] validity status: " + refValid);
        }
    } else {
        System.out.println("Signature passed core validation");
        break;
    }
}
}

private static class KeyValueKeySelector extends KeySelector {

    public KeySelectorResult select(KeyInfo keyInfo,
            KeySelector.Purpose purpose,
            AlgorithmMethod method,
            XMLCryptoContext context)
            throws KeySelectorException {
        if (keyInfo == null) {
            throw new KeySelectorException("Null KeyInfo object!");
        }
        SignatureMethod sm = (SignatureMethod) method;
        List list = keyInfo.getContent();

        for (int i = 0; i < list.size(); i++) {
            XMLStructure xmlStructure = (XMLStructure) list.get(i);
            if (xmlStructure instanceof KeyValue) {
                PublicKey pk = null;
                try {
                    pk = ((KeyValue) xmlStructure).getPublicKey();
                } catch (KeyException ke) {
                    throw new KeySelectorException(ke);
                }
                // make sure algorithm is compatible with method
                if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) {
                    return new SimpleKeySelectorResult(pk);
                }
            } 

        }
        throw new KeySelectorException("No KeyValue element found!");
    }

    static boolean algEquals(String algURI, String algName) {
        if (algName.equalsIgnoreCase("DSA")
                && algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) {
            return true;
        } else if (algName.equalsIgnoreCase("RSA")
                && algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1)) {
            return true;
        } else {
            return false;
        }
    }
}

private static class SimpleKeySelectorResult implements KeySelectorResult {

    private PublicKey pk;

    SimpleKeySelectorResult(PublicKey pk) {
        this.pk = pk;
    }

    public Key getKey() {
        return pk;
    }
}
4

1 回答 1

3

XML 签名核心验证包括 2 个阶段:

  • 参考验证
  • 签名验证

引用验证是对 XML 签名中每个引用 (URI) 的消息摘要的验证。

签名验证是对签名内容或 SignedInfo 元素的签名的验证。

两个阶段都必须通过才能使 XML 签名有效。

在您的情况下,参考验证通过,但签名验证失败,即。签名元素被篡改,而引用元素或签名的 URI 未被篡改。

所以最终核心签名验证失败了。

请参阅此处以获取更多说明。

于 2013-06-12T11:46:17.517 回答