2013-07-03 34 views
1

我有xades XML作爲InputStream。我不在乎證書是否有效,檢查簽名等。我無法提供任何CA或任何其他類型的證書存儲/驗證。我需要的只是將文件嵌入到xades文件中作爲磁盤上的流或臨時文件,這樣我就可以將它們作爲磁盤上的純文件進行處理。有人可以提供摘錄嵌入文檔的摘錄嗎? TIA如何在Java xades4j中提取xades簽名的內容?

+0

你嘗試過這麼遠嗎?你可以發佈一些代碼,以及你想要做什麼的更多細節?否則很難確定如何提供幫助。 –

+0

我不知道該如何開始。我知道我必須先解開XML,但xades4j是否提供了接口?我需要自己解析XML嗎?我完全是綠色的... – redguy

+0

好的。我在這裏找到了一些代碼:https://code.google.com/p/xades4j/issues/detail?id=37 這指出我使用DocumentBuilderFactory和DocumentBuilder解析xml文件。我會遵循這條線索。 – redguy

回答

0

要從XAdES簽名文件中提取Base64編碼的簽名內容,我使用下面的代碼。它根本不使用xades4j。

import java.io.InputStream; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.Map; 

import javax.xml.namespace.NamespaceContext; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.xpath.XPath; 
import javax.xml.xpath.XPathConstants; 
import javax.xml.xpath.XPathExpression; 
import javax.xml.xpath.XPathFactory; 

import org.bouncycastle.util.encoders.Base64; 
import org.w3c.dom.Document; 
import org.w3c.dom.NamedNodeMap; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 

public class Utils { 

    /** 
    * extract ds:Object from .xades file 
    * 
    * @param xadesIn .xades file input stream 
    * @return base64 decoded bytes 
    * @throws Exception 
    */ 
    public static byte[] extractContentFromXadesSignedFile(InputStream xadesIn) throws Exception { 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     dbf.setNamespaceAware(true); 
     Document doc = dbf.newDocumentBuilder().parse(xadesIn); 
     xadesIn.close();     
     XPathFactory xPathfactory = XPathFactory.newInstance(); 
     XPath xpath = xPathfactory.newXPath(); 
     xpath.setNamespaceContext(new SimpleNamespaceContext(new HashMap<String, String>() {{ 
      put("ds", "http://www.w3.org/2000/09/xmldsig#"); 
     }})); 

     XPathExpression expr = xpath.compile("//ds:SignedInfo/ds:Reference"); 
     NodeList referenceNodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); 

     /** 
     * loop over all Reference nodes 
     * i need to find Object node with Id that fits URI value of Reference 
     */ 
     for(int i=0;i<referenceNodes.getLength();i++){ 
      Node referenceNode = referenceNodes.item(i); 
      NamedNodeMap attributes = referenceNode.getAttributes(); 
      if(attributes != null) { 
       Node uri = attributes.getNamedItem("URI"); 
       if(uri != null) { 
        String objectId = uri.getNodeValue(); 
        XPathExpression expr2 = xpath.compile("//ds:Object[@Id='"+objectId.substring(1)+"']"); 
        Node contentNode = (Node) expr2.evaluate(doc, XPathConstants.NODE); 
        if(contentNode != null) { 
         String base64 = contentNode.getFirstChild().getNodeValue(); 
         return Base64.decode(base64); 
        } 
       } 
      } 
     } 

     return null; 
    } 

    /** 
    * http://stackoverflow.com/a/6392700/404395 
    */ 
    private static class SimpleNamespaceContext implements NamespaceContext { 

     private final Map<String, String> PREF_MAP = new HashMap<String, String>(); 

     public SimpleNamespaceContext(final Map<String, String> prefMap) { 
      PREF_MAP.putAll(prefMap);  
     } 

     @Override 
     public String getNamespaceURI(String prefix) { 
      return PREF_MAP.get(prefix); 
     } 

     @Override 
     public String getPrefix(String uri) { 
      throw new UnsupportedOperationException(); 
     } 

     @Override 
     public Iterator getPrefixes(String uri) { 
      throw new UnsupportedOperationException(); 
     } 

    }  
} 

的是使用範例:

import java.io.ByteArrayInputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.InputStream; 

import org.apache.commons.io.IOUtils; 
import org.junit.Assert; 
import org.junit.Test; 

public class XadesExtractTest { 

    @Test 
    public void extract() throws Exception { 
     InputStream in = XadesExtractTest.class.getClassLoader().getResourceAsStream("test.xades"); 
     byte[] bytes = Utils.extractContentFromXadesSignedFile(in); 
     Assert.assertNotNull(bytes); 
     in.close(); 
     ByteArrayInputStream bin = new ByteArrayInputStream(bytes); 
     File f = File.createTempFile("test", ".zip"); 
     System.out.println(f.getAbsolutePath()); 
     FileOutputStream fout = new FileOutputStream(f); 
     IOUtils.copy(bin, fout); 
     bin.close(); 
     fout.close(); 
    } 
}