Validating javax.xml.crypto.dsig using public key in xml

Using javax.xml.crypto.dsig, how can I untie and validate XMLSignature without specifying a public key? The public key seems to be in signed xml, but I can't figure out how to get it.

DOMValidateContext valContext = new DOMValidateContext(key,signatureNode);
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
boolean coreValidity = signature.validate(valContext);

As far as I can tell, it is necessary to pass the KeySelector instead of the key to the DOMValidateContext. However, I cannot figure out how to implement KeySelector.

Here is the only example I found on how to implement KeySelector:    http://download.oracle.com/javase/6/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html

Unfortunately this will not work. In this implementation, it does the following, but always fails because there are no KeyValue elements (it seems that instead of KeyValue elements they are org.jcp.xml.dsig.internal.dom.DOMX509Data elements that do not have the key to them).

List list = keyInfo.getContent();

for (int i = 0; i < list.size(); i++) {
    XMLStructure xs = (XMLStructure) list.get(i);
    if(xs instanceof KeyValue) {
        PublicKey pk = null;
        try {
            pk = ((KeyValue) xs).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!");

So is there a way to do this? I want to be able to verify the signature of an xml file without having a public key. I just want to get the public key from xml.

+5
source share
2 answers

Extend the if () condition that you checked to see if xs is an instance of KeyValue, to also check the X509Data instance as follows:

else if (xs instanceof X509Data) {
     for (Object data : ((X509Data) xs).getContent()) {
          if (data instanceof X509Certificate) {
              pk = ((X509Certificate) data).getPublicKey();
          }
     }
}
+5
source