我正在尝试验证signed XML document,但它总是失败。我构建的代码主要包含Oracle托管的代码。有没有办法可以公开更多信息以便能够调试这种情况?代码或签名的XML文档有问题吗?输出是:
Signature failed core validation
signature validation status: true
这是主要的代码集:
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
import javax.xml.XMLConstants;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.SAXException;
public class Validate {
private static Schema getXSD() {
try {
InputStream xsd = Validate.class.getResourceAsStream("xsd/saml-schema-metadata-2.0.xsd");
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
factory.setResourceResolver(new LSResourceResolver() {
@Override
public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
InputStream resourceAsStream = Validate.class.getResourceAsStream(systemId);
return new XSDInput(publicId, systemId, resourceAsStream);
}
});
return factory.newSchema(new StreamSource(xsd));
} catch (SAXException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException {
Schema xsdSchema = Validate.getXSD();
URL certsURL = new URL("https://ds.aaf.edu.au/distribution/metadata/metadata.aaf.signed.minimal.xml");
InputStream certsInputStream = certsURL.openStream();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setSchema(xsdSchema);
Document document = dbf.newDocumentBuilder().parse(certsInputStream);
// Find Signature element.
NodeList nl = document.getElementsByTagNameNS(
XMLSignature.XMLNS, "Signature"
);
if (nl.getLength() == 0) {
System.err.println("No signature element");
return;
}
// Create a DOMValidateContext and specify a KeySelector
// and document context.
DOMValidateContext valContext = new DOMValidateContext(
new X509KeySelector(), nl.item(0)
);
// Unmarshal the XMLSignature.
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
try {
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
boolean coreValidity = signature.validate(valContext);
if (coreValidity == false) {
System.err.println("Signature failed core validation");
boolean sv = signature.getSignatureValue().validate(valContext);
System.out.println("signature validation status: " + sv);
if (sv == false) {
// 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");
}
} catch (MarshalException e) {
e.printStackTrace();
} catch (XMLSignatureException e) {
e.printStackTrace();
}
}
}
我在这里举办了一个完整的例子: https://github.com/markwallsgrove/xmlvalidation-issue/tree/master/src