2011-01-13 15 views
5

Utilizzando javax.xml.crypto.dsig, come si esegue unmarshal e convalida una XMLSignature senza specificare la chiave pubblica? La chiave pubblica sembra essere nell'xml firmato, ma non riesco a capire come ottenerlo.convalida javax.xml.crypto.dsig utilizzando la chiave pubblica nell'xml

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

Per quanto posso dire che è necessario superare un KeySelector invece di una chiave per la DOMValidateContext. Tuttavia, non riesco a capire come implementare un KeySelector.

Qui è l'unico esempio che ho trovato su come implementare un KeySelector: http://download.oracle.com/javase/6/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html

Purtroppo non funziona. In questa implementazione fa quanto segue, ma fallisce sempre perché non ci sono elementi KeyValue (sembra che al posto degli elementi KeyValue siano org.jcp.xml.dsig.internal.dom.DOMX509 Elementi dati che non hanno un modo di ge chiave da loro).

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!"); 

Quindi, c'è un modo per farlo? Voglio essere in grado di convalidare la firma di un file xml senza dover avere la chiave pubblica. Voglio solo ottenere la chiave pubblica dal xml.

risposta

5

Estendere la condizione if() è stato il controllo per vedere se xs è un esempio di KeyValue di controllare anche istanza di X509Data come segue:

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

si noti che la classe 'X509Certificate' qui ha bisogno di essere' java.security.cert .X509Certificate' e non 'javax.security.cert.X509Certificate'. –