我已经签署了一份xml文档,我正在尝试验证签名。
我一直在浏览XML API中提供的示例代码,如下所示
检查验证后, 它说核心衰退失败了 签名验证失败,但引用有效性为真。
这些类型的验证有何不同以及应该考虑什么来说明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;
}
}
答案 0 :(得分:3)
XML签名核心验证包括两个阶段:
参考验证是对XML签名中每个引用(URI)的消息摘要的验证。
签名验证是对签名内容或SignedInfo元素的签名进行验证。
两个阶段必须通过才能使XML签名生效。
在您的情况下,传递了引用验证,但签名验证失败,即。签名元素被篡改,参考元素或签名的URI不是。
因此最终核心签名验证失败。