2013-05-09 87 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.