1
我有xades XML作爲InputStream。我不在乎證書是否有效,檢查簽名等。我無法提供任何CA或任何其他類型的證書存儲/驗證。我需要的只是將文件嵌入到xades文件中作爲磁盤上的流或臨時文件,這樣我就可以將它們作爲磁盤上的純文件進行處理。有人可以提供摘錄嵌入文檔的摘錄嗎? TIA如何在Java xades4j中提取xades簽名的內容?
我有xades XML作爲InputStream。我不在乎證書是否有效,檢查簽名等。我無法提供任何CA或任何其他類型的證書存儲/驗證。我需要的只是將文件嵌入到xades文件中作爲磁盤上的流或臨時文件,這樣我就可以將它們作爲磁盤上的純文件進行處理。有人可以提供摘錄嵌入文檔的摘錄嗎? TIA如何在Java xades4j中提取xades簽名的內容?
要從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();
}
}
你嘗試過這麼遠嗎?你可以發佈一些代碼,以及你想要做什麼的更多細節?否則很難確定如何提供幫助。 –
我不知道該如何開始。我知道我必須先解開XML,但xades4j是否提供了接口?我需要自己解析XML嗎?我完全是綠色的... – redguy
好的。我在這裏找到了一些代碼:https://code.google.com/p/xades4j/issues/detail?id=37 這指出我使用DocumentBuilderFactory和DocumentBuilder解析xml文件。我會遵循這條線索。 – redguy