Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javax.xml.crypto.dsig validation using the public key in the xml

Using javax.xml.crypto.dsig, how do I unmarshal and validate an XMLSignature without specifying the public key? The public key appears to be in the signed xml, but I can't figure out a way 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's necessary to pass a KeySelector instead of a Key to the DOMValidateContext. However, I can't figure out how to implement a KeySelector.

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

Unfortunately it doesn't work. In that implementation it does the following but always fails because there are no KeyValue elements (it appears that instead of KeyValue elements they are org.jcp.xml.dsig.internal.dom.DOMX509Data elements which don't have a way to ge the key from 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 validate the signature of an xml file without having to have the public key. I just want to get the public key from the xml.

like image 298
HappyEngineer Avatar asked Jan 13 '11 01:01

HappyEngineer


2 Answers

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

else if (xs instanceof X509Data) {
     for (Object data : ((X509Data) xs).getContent()) {
          if (data instanceof X509Certificate) {
              pk = ((X509Certificate) data).getPublicKey();
          }
     }
}
like image 57
Καrτhικ Avatar answered Nov 13 '22 02:11

Καrτhικ


just include xmldsig.jar to your build path and check the JDK of yours for 1.5 you have to add to your build path for 1.6 they have inbuilt in it so no need to add for reference http://java.sun.com/developer/technicalArticles/xml/dig_signature_api/

like image 30
Sundar G Avatar answered Nov 13 '22 04:11

Sundar G