2012-07-09 9 views
6

He leído muchas cosas para configurar mi sistema cliente/servidor SSL (sin HTTP).Netty SSL: cómo escribir un TrustManager

Me inspiré de the secure chat example y the websocket ssl server example. ya creado mi archivo cert.jks con el comando

keytool -genkey -alias app-keysize 2048 -validity 36500 
-keyalg RSA -dname "CN=app" 
-keypass mysecret-storepass mysecret 
-keystore cert.jks 

En el ejemplo de chat seguro existe esta clase:

public class SecureChatTrustManagerFactory extends TrustManagerFactorySpi { 

    private static final TrustManager DUMMY_TRUST_MANAGER = new X509TrustManager() { 
     @Override 
     public X509Certificate[] getAcceptedIssuers() { 
      return new X509Certificate[0]; 
     } 

     @Override 
     public void checkClientTrusted(
       X509Certificate[] chain, String authType) throws CertificateException { 
      // Always trust - it is an example. 
      // You should do something in the real world. 
      // You will reach here only if you enabled client certificate auth, 
      // as described in SecureChatSslContextFactory. 
      System.err.println(
        "UNKNOWN CLIENT CERTIFICATE: " + chain[0].getSubjectDN()); 
     } 

     @Override 
     public void checkServerTrusted(
       X509Certificate[] chain, String authType) throws CertificateException { 
      // Always trust - it is an example. 
      // You should do something in the real world. 
      System.err.println(
        "UNKNOWN SERVER CERTIFICATE: " + chain[0].getSubjectDN()); 
     } 
    }; 

    public static TrustManager[] getTrustManagers() { 
     return new TrustManager[] { DUMMY_TRUST_MANAGER }; 
    } 

    @Override 
    protected TrustManager[] engineGetTrustManagers() { 
     return getTrustManagers(); 
    } 

    @Override 
    protected void engineInit(KeyStore keystore) throws KeyStoreException { 
     // Unused 
    } 

    @Override 
    protected void engineInit(ManagerFactoryParameters managerFactoryParameters) 
      throws InvalidAlgorithmParameterException { 
     // Unused 
    } 
} 

Procedimiento de implantación de esta clase correctamente?

Y en este código (en la clase SecureChatSslContextFactory):

SSLContext serverContext = null; 
    SSLContext clientContext = null; 
    try { 
     KeyStore ks = KeyStore.getInstance("JKS"); 
     ks.load(SecureChatKeyStore.asInputStream(), 
       SecureChatKeyStore.getKeyStorePassword()); 

     // Set up key manager factory to use our key store 
     KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); 
     kmf.init(ks, SecureChatKeyStore.getCertificatePassword()); 

     // Initialize the SSLContext to work with our key managers. 
     serverContext = SSLContext.getInstance(PROTOCOL); 
     serverContext.init(kmf.getKeyManagers(), null, null); 
    } catch (Exception e) { 
     throw new Error(
       "Failed to initialize the server-side SSLContext", e); 
    } 

    try { 
     clientContext = SSLContext.getInstance(PROTOCOL); 
     clientContext.init(null, SecureChatTrustManagerFactory.getTrustManagers(), null); 
    } catch (Exception e) { 
     throw new Error(
       "Failed to initialize the client-side SSLContext", e); 
    } 

¿Por qué ponen null en lugar de tmf.getTrustManagers() en la línea de serverContext.init(kmf.getKeyManagers(), null, null);?

Respuesta

9

¿Cómo se implementa esta clase correctamente?

Debe definir una forma de comprobar que confía en el certificado en chain[0] de una forma u otra. Si no lo haces, lanza un CertificateException. (Aquí el SecureChatTrustManagerFactory nunca tira nada, así que no pasa la verificación, que puede hacer la conexión abierta a los ataques MITM.)

Si usted quiere hacer esta verificación semi-manual, puede utilizar el Java PKI API, aunque it can be a bit tedious, incluso en casos de uso relativamente simples.

En términos generales, lo correcto es no para implementar el suyo. Deje eso al TrustManagerFactory (más o menos de la misma manera que se hace con el KeyManagerFactory). Por cierto, en ambos casos, recomendaría usar Key/TrustManagerFactory.getDefaultAlgorithm() por el valor de algorithm, a menos que tenga una buena razón para no hacerlo. Al menos es un valor predeterminado mejor que SunX509 que he visto codificado en muchos casos (y que de hecho no es el valor predeterminado del algoritmo TMF).

Puede inicializar un TMF desde su propio truststore (una instancia de KeyStore que puede cargar específicamente para esta conexión, por ejemplo).

¿Por qué ponen nulo en lugar de tmf.getTrustManagers() en la línea serverContext.init (kmf.getKeyManagers(), null, null); ?

null para los administradores de confianza y null para la SecureRandom caída de nuevo a los valores por defecto. Este será un administrador de confianza predeterminado inicializado con el algoritmo TMF predeterminado (generalmente PKIX), utilizando el almacén de confianza predeterminado (usando la ubicación en javax.net.ssl.trustStore, o volviendo al archivo jssecacerts o cacerts). Más detalles en el JSSE reference guide.

+1

Todavía no logramos que algo funcione ... No veo cómo implementar mi propia TrustManagerFactory – Nanocom

+1

No implemente su propia TMF, use la existente. – Bruno

+0

Lo siento, quise decir que no pude implementar mi propia SecureChatSslContextFactory – Nanocom