哪个结果验证签名的XML - 核心验证,签名验证和参考验证

时间:2013-05-09 05:36:08

标签: java xml xml-signature

我已经签署了一份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;
    }
}

1 个答案:

答案 0 :(得分:3)

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

  • 参考验证
  • 签名验证

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

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

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

在您的情况下,传递了引用验证,但签名验证失败,即。签名元素被篡改,参考元素或签名的URI不是。

因此最终核心签名验证失败。

Refer here for more explanation.