javasslnettysslcontext

build io.netty.handler.ssl.SslContext with just a .key and a .crt


I have a question regarding how to build a Netty io.netty.handler.ssl.SslContext with just a .key (dot key) file and a .crt (dot crt) file.

To emphasize, I am looking for help to build a io.netty.handler.ssl.SslContext, not org.apache.http.ssl.SSLContexts.

Also, I am looking for help building the io.netty.handler.ssl.SslContext, without ready made keystore and truststore. (will not be able to do that directly)

public SslContext getSslContext() {
        try {
            final Path     keystorePath = Paths.get(keyStorePath);
            final KeyStore keyStore     = KeyStore.getInstance(keyStoreType);
            try (InputStream keyStoreFile = Files.newInputStream(keystorePath)) {
                keyStore.load(keyStoreFile, keyStorePassPhrase.toCharArray());
            }
            final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, keyPassPhrase.toCharArray());

            final Path     truststorePath = Paths.get(trustStorePath);
            final KeyStore trustStore     = KeyStore.getInstance(trustStoreType);
            try (InputStream trustStoreFile = Files.newInputStream(truststorePath)) {
                trustStore.load(trustStoreFile, trustStorePassPhrase.toCharArray());
            }
            final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(trustStore);

            return SslContextBuilder.forClient().keyManager(keyManagerFactory).trustManager(trustManagerFactory).build();
        } catch (KeyStoreException | IOException | UnrecoverableKeyException | NoSuchAlgorithmException | CertificateException e) {
            
            return null;
        }
    }

What would be the easiest way please?

Thank you


Solution

  • Netty is able to load pem formatted private key and certificate as a key material. It is built in within the SslContextBuilder, see below for an example:

    SslContext sslContext = SslContextBuilder.forClient()
        .keyManager(new File("/path/to/certificate.crt"), new File("/path/to/private.key"), "secret")
        .build();
    

    See below for the javadoc of the method

       /**
         * Identifying certificate for this host. {@code keyCertChainFile} and {@code keyFile} may
         * be {@code null} for client contexts, which disables mutual authentication.
         *
         * @param keyCertChainFile an X.509 certificate chain file in PEM format
         * @param keyFile a PKCS#8 private key file in PEM format
         * @param keyPassword the password of the {@code keyFile}, or {@code null} if it's not
         *     password-protected
         */
        public SslContextBuilder keyManager(File keyCertChainFile, File keyFile, String keyPassword) {
        ...
        }
    

    Regarding your second question for generating a netty ssl context without the usage of keystore I would advise to use Bouncy castle library to create private keypair as keymaterial which you can supply to netty sslcontext builder. See here for a reference for creating a private key pair with bouncy castle: Generating keyPair using Bouncy Castle

    See below for the method which can be used to supply private key and certificates which are generated by bouncy castle

        /**
         * Identifying certificate for this host. {@code keyCertChain} and {@code key} may
         * be {@code null} for client contexts, which disables mutual authentication.
         *
         * @param key a PKCS#8 private key
         * @param keyCertChain an X.509 certificate chain
         */
        public SslContextBuilder keyManager(PrivateKey key, Iterable<? extends X509Certificate> keyCertChain) {
            return keyManager(key, toArray(keyCertChain, EMPTY_X509_CERTIFICATES));
        }