-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Getting a SSLContext from different sources
A SSLContext
is used to secure your 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.
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;
}
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));
}
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;
}