2010-12-20 4 views
2

Ich muss ein signiertes XML-Dokument überprüfen. Als Teil der Verifizierung muss ich überprüfen, ob das mit dem signierten Zertifikat übergebene Zertifikat ein vertrauenswürdiges Zertifikat ist.So überprüfen Sie, ob ein Zertifikat in einem Keystore vorhanden ist

Alle vertrauenswürdigen Zertifikate werden einem Schlüsselspeicher mit der Bezeichnung trusted.keystore hinzugefügt.

Wie kann ich überprüfen, ob das übergebene Zertifikat ein gültiges Zertifikat ist?

Ich habe schrieb folgende KeySelector, aber es funktioniert nicht

import java.security.Key; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.PublicKey; 
import java.security.cert.Certificate; 
import java.security.cert.X509Certificate; 
import java.util.Enumeration; 
import java.util.Iterator; 

import javax.xml.crypto.AlgorithmMethod; 
import javax.xml.crypto.KeySelector; 
import javax.xml.crypto.KeySelectorException; 
import javax.xml.crypto.KeySelectorResult; 
import javax.xml.crypto.XMLCryptoContext; 
import javax.xml.crypto.XMLStructure; 
import javax.xml.crypto.dsig.SignatureMethod; 
import javax.xml.crypto.dsig.keyinfo.KeyInfo; 
import javax.xml.crypto.dsig.keyinfo.X509Data; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 

public class X509KeySelector extends KeySelector { 
    private static Log log = LogFactory.getLog(X509KeySelector.class); 

    private KeyStore trustedStore; 

    public void setTrustedStore(KeyStore trustedStore) { 
     this.trustedStore = trustedStore; 
    } 

    @SuppressWarnings("rawtypes") 
    public KeySelectorResult select(KeyInfo keyInfo, 
      KeySelector.Purpose purpose, AlgorithmMethod method, 
      XMLCryptoContext context) throws KeySelectorException { 
     if (log.isDebugEnabled()) { 
      log.debug("Selecting key for algorithm: " + method.getAlgorithm()); 
     } 

     Iterator ki = keyInfo.getContent().iterator(); 
     while (ki.hasNext()) { 
      XMLStructure info = (XMLStructure) ki.next(); 
      if (log.isDebugEnabled()) { 
       log.debug("Found xml structure: " + info.toString()); 
      } 

      if (!(info instanceof X509Data)) { 
       if (log.isTraceEnabled()) { 
        log.trace("Ignoring xml structure since it is not a X509Data."); 
       } 
       continue; 
      } 

      X509Data x509Data = (X509Data) info; 
      Iterator xi = x509Data.getContent().iterator(); 
      if (log.isDebugEnabled()) { 
       log.debug("Iterating X509Data: Size: " 
         + x509Data.getContent().size()); 
      } 

      while (xi.hasNext()) { 
       Object o = xi.next(); 
       if (log.isDebugEnabled()) { 
        log.debug("Found object: " + o); 
       } 

       if (!(o instanceof X509Certificate)) { 
        if (log.isTraceEnabled()) { 
         log.trace("Ignoring object since it is not a X509Certificate"); 
        } 
        continue; 
       } 
       X509Certificate cert = (X509Certificate) o; 
       if (!isTrustedCertificate(cert)) { 
        log.warn("Ignoring certificate since it is not a valid certificate. Certificate: " 
          + cert); 
        continue; 
       } 

       final PublicKey key = cert.getPublicKey(); 

       // Make sure the algorithm is compatible 
       // with the method. 
       if (algEquals(method.getAlgorithm(), key.getAlgorithm())) { 
        KeySelectorResult keySelectorResult = new KeySelectorResult() { 
         public Key getKey() { 
          return key; 
         } 
        }; 
        return keySelectorResult; 
       } else { 
        log.warn("Ignoring certificate since the algorithms " 
          + method.getAlgorithm() + " and " 
          + key.getAlgorithm() + " does not match."); 
       } 
      } 
     } 

     log.error("Unable to find a valid certificate."); 
     throw new KeySelectorException("No key found!"); 
    } 

    private boolean isTrustedCertificate(X509Certificate cert) { 
     if (trustedStore == null) { 
      return true; 
     } 

     boolean trusted = false; 
     try { 
      Enumeration<String> aliases = trustedStore.aliases(); 
      while (aliases.hasMoreElements()) { 
       String alias = aliases.nextElement(); 

       Certificate[] certificates = this.trustedStore 
         .getCertificateChain(alias); 
       if (certificates == null) { 
        Certificate certificate = this.trustedStore 
          .getCertificate(alias); 
        if (certificate != null) { 
         certificates = new Certificate[] { certificate }; 
        } 
       } 

       if (certificates != null) { 
        for (Certificate certificate : certificates) { 
         if (!(certificate instanceof X509Certificate)) { 
          continue; 
         } 

         if (cert.getSignature().equals(
           ((X509Certificate) certificate).getSignature())) { 
          trusted = true; 
          break; 
         } 
        } 
        if (trusted) { 
         break; 
        } 
       } 
      } 
     } catch (KeyStoreException e) { 
      log.error(e.toString(), e); 
     } 
     return trusted; 
    } 

    static boolean algEquals(String algURI, String algName) { 
     if ((algName.equalsIgnoreCase("DSA") && algURI 
       .equalsIgnoreCase(SignatureMethod.DSA_SHA1)) 
       || (algName.equalsIgnoreCase("RSA") && algURI 
         .equalsIgnoreCase(SignatureMethod.RSA_SHA1))) { 
      return true; 
     } else { 
      return false; 
     } 
    } 
} 

Das Problem liegt in dem Verfahren isTrustedCertificate. Wo ich durch alle Aliase im Keystore iteriere und überprüfe, wo es das übergebene Zertifikat ist.

Wie der Klassenname andeutet, handelt es sich nur um Zertifikate vom Typ X509.

Danke

Antwort

1

Ich glaube, ich war auf dem falschen Weg,

ich das überprüfen (PublicKey) -Methode in Zertifikatsobjekt gefunden, die java.security.SignatureException: Signature does not match. Ausnahme, wenn die Zertifikate nicht übereinstimmt.

1

Es gibt eine einfachere Möglichkeit, dies mit einer Methode zu überprüfen, die zunächst nicht offensichtlich ist. Die KeyStore-Klasse verfügt über eine Methode namens getCertificateAlias ​​(Zertifikat-Zertifikat). Wenn Sie das Zertifikat übergeben, nach dem Sie suchen, und keine Nullrückgabe erhalten, befindet sich dieses Zertifikat im KeyStore.

versuchen, etwas wie folgt aus:

private boolean isTrustedCertificate(X509Certificate cert) { 

    if (trustedStore == null) { 
     return true; 
    } 

    boolean trusted = false; 
    try { 

    if (cert != null) { 

     // Only returns null if cert is NOT in keystore. 
     String alias = trustedStore.getCertificateAlias(cert); 

     if (alias != null) { 
      trusted = true; 
     } 
    } 
    } catch (KeyStoreException e) { 
     log.error(e.toString(), e); 
    } 

    return trusted; 
} 
Verwandte Themen