Skip to content

Getting a SSLContext from different sources

Marcel Prestel edited this page May 9, 2018 · 8 revisions

Introduction

A SSLContext is used to secure your websocket connection.

Secure a websocket connection

To secure your connection, e.g. to use a websocket-connection on a https site, you have to add the following lines to your WebsocketServer class.

SSLContext sslContext = <method>;
setWebSocketFactory(new DefaultSSLWebSocketServerFactory(sslContext));

Please choose from one of the following examples provided.

If you found another way to implement this, feel free to share it with us.

Getting a SSLContext using a keystore

Credits to bendem on github.com for sharing his code.

You can find an example how to generate your keystore here.

Please adjust the variables keystore, storePassword and keyPassword accordingly.

/**
* Method which returns a SSLContext from a keystore or IllegalArgumentException on error
*
* @return a valid SSLContext
* @throws IllegalArgumentException when some exception occurred 
*/
private SSLContext getSSLConextFromKeystore() {
    // load up the key store
    String storeType = "JKS";
    String keystore = "server.keystore";
    String storePassword = "storePassword";
    String keyPassword = "keyPassword";

    KeyStore ks;
    SSLContext sslContext;
    try {
        ks = KeyStore.getInstance(storeType);
        ks.load(Files.newInputStream(Paths.get("..", keystore)), storePassword.toCharArray());
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, keyPassword.toCharArray());
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
        tmf.init(ks);


        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
    } catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException e) {
       throw new IllegalArgumentException();
    }
    return sslContext;
}

Getting a SSLContext using a Let’s Encrypt certificate

Credits to Ryan on stackoverflow.com for sharing his code. I (marci4) modified it a bit for my needs!

WARNING: You may have to include the current chain for the certificate!

Please adjust the variables pathTo and keyPassword accordingly.

/**
* Method which returns a SSLContext from a Let's encrypt or IllegalArgumentException on error
*
* @return a valid SSLContext
* @throws IllegalArgumentException when some exception occurred 
*/
private SSLContext getSSLContextFromLetsEncrypt() {
    SSLContext context;
    String pathTo = "pem";
    String keyPassword = "keyPassword";
    try {
        context = SSLContext.getInstance("TLS");

        byte[] certBytes = parseDERFromPEM(Files.readAllBytes(new File(pathTo + File.separator + "cert.pem").toPath()), "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----");
        byte[] keyBytes = parseDERFromPEM(Files.readAllBytes(new File(pathTo + File.separator + "privkey.pem").toPath()), "-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----");

        X509Certificate cert = generateCertificateFromDER(certBytes);
        RSAPrivateKey key = generatePrivateKeyFromDER(keyBytes);

        KeyStore keystore = KeyStore.getInstance("JKS");
        keystore.load(null);
        keystore.setCertificateEntry("cert-alias", cert);
        keystore.setKeyEntry("key-alias", key, keyPassword.toCharArray(), new Certificate[]{cert});

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(keystore, keyPassword.toCharArray());

        KeyManager[] km = kmf.getKeyManagers();

        context.init(km, null, null);
    } catch (IOException | KeyManagementException | KeyStoreException | InvalidKeySpecException | UnrecoverableKeyException | NoSuchAlgorithmException | CertificateException e) {
        throw new IllegalArgumentException();
    }        
    return context;
}

protected static byte[] parseDERFromPEM(byte[] pem, String beginDelimiter, String endDelimiter) {
    String data = new String(pem);
    String[] tokens = data.split(beginDelimiter);
    tokens = tokens[1].split(endDelimiter);
    return DatatypeConverter.parseBase64Binary(tokens[0]);
}

protected static RSAPrivateKey generatePrivateKeyFromDER(byte[] keyBytes) throws InvalidKeySpecException, NoSuchAlgorithmException {
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory factory = KeyFactory.getInstance("RSA");
    return (RSAPrivateKey) factory.generatePrivate(spec);
}

protected static X509Certificate generateCertificateFromDER(byte[] certBytes) throws CertificateException {
    CertificateFactory factory = CertificateFactory.getInstance("X.509");

    return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(certBytes));
}

Getting a SSLContext using a keystore on Android

This code is adjusted to the Android keystore system.

/**
* Method which returns a SSLContext from a keystore on Android or IllegalArgumentException on error
*
* @return a valid SSLContext
* @throws IllegalArgumentException when some exception occurred 
*/
private SSLContext getSSLConextFromAndroidKeystore() {
    // load up the key store
    String storePassword = "storePassword";
    String keyPassword = "keyPassword";

    KeyStore ks;
    SSLContext sslContext;
    try {
         KeyStore keystore = KeyStore.getInstance("BKS");
         InputStream in = getResources().openRawResource(R.raw.keystore);
         try {
             keystore.load(in, storePassword.toCharArray());
         } finally {
             in.close();
         }
         KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");
         keyManagerFactory.init(keystore, keyPassword .toCharArray());
         TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
         tmf.init(keystore);

         sslContext = SSLContext.getInstance("TLS");
         sslContext.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
    } catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException e) {
       throw new IllegalArgumentException();
    }
    return sslContext;
}