Netty SSL: how to write TrustManager

I read a lot of material for setting up my client / server SSL system (without HTTP).

I inspired myself with the example of secure chat and the ssl server server ssl example . A cert.jks file has already been created with the command

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

The secure chat example has this class:

 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 } } 

How do you implement this class correctly?

And in this code (in the SecureChatSslContextFactory class):

  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); } 

Why do they put null instead of tmf.getTrustManagers() in the line serverContext.init(kmf.getKeyManagers(), null, null); ?

+6
source share
1 answer

How do you implement this class correctly?

You need to determine how to verify that you trust the certificate in chain[0] anyway. If you do not, throw a CertificateException . (Here, SecureChatTrustManagerFactory never throws anything away, so it bypasses the check, which can open a connection with MITM attacks.)

If you want to do this check semi-manually, you can use the Java PKI API , although it can be a bit tedious , even in relatively simple use cases.

Generally speaking, the right thing is not to realize your own. Leave this in TrustManagerFactory (more or less in the same way as with KeyManagerFactory ). By the way, in both cases, I recommend using Key/TrustManagerFactory.getDefaultAlgorithm() for the algorithm value if you have no good reason. This is at least a better default than the SunX509 , which in many cases I have seen hardcoded (and in fact it is not the default for TMF).

You can initialize TMF from your own trust store (for example, an instance of KeyStore , which you can download specifically for this connection, for example).

Why do they put null instead of tmf.getTrustManagers () in the line serverContext.init (kmf.getKeyManagers (), null, null);

null for trust managers and null for SecureRandom reverts to default values. This will be the default trust manager initialized by the default TMF algorithm (usually PKIX ) using the default trust store (using the location in javax.net.ssl.trustStore or returning to the jssecacerts or cacerts ). Read more in the JSSE Reference Guide .

+9
source

Source: https://habr.com/ru/post/920038/


All Articles