Skip to content

Getting a SSLContext from different sources

Marcel P edited this page Mar 19, 2017 · 8 revisions

Introduction

A SSLContext is used to secure your websocket connection.

Secure a websocket connection

To secure your connection, you have to add the following lines to your WebsocketServer class.

SSLContext sslContext = <method>;
if (sslContext != null) {
	setWebSocketFactory(new DefaultSSLWebSocketServerFactory(sslContext));
}

Please choose from one of the following examples provided.

Getting a SSLContext using a keystore

/**
* Method which returns a SSLContext from a keystore or null if an exception occurred
*
* @return a valid SSLContext or null if an error 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) {
		return null;
	}
	return sslContext;
}

Getting a SSLContext a Let's encrypt certificate

/**
* Method which returns a SSLContext from a Let's encrypt or null if an exception occurred
*
* @return a valid SSLContext or null if an error 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) {
		return null;
	}        
	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));
}