2013-05-09 56 views
0

我已经签署了一个xml文档,并试图验证签名。哪个结果验证签名的XML - 核心验证,签名验证和引用验证

我一直在经历的XML API给出的示例代码如下

检查确认后, 它说核心valdiation失败 签名验证失败,但引用的有效性为真。

如何在这些类型的验证的不同,应视为声明,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; 
    } 
} 

回答

3

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

  • 参考验证
  • 签名验证

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

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

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

在你的情况下,参考验证通过,但签名验证失败,即。签名元素被篡改,并且参考元素或URI签名不是。

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

Refer here for more explanation.