While implementing SSL socket connection based on native Android I used the below code, which worked fine.
Now, if I've to implement a similar thing using socket.io, what's the procedure for that?
`KeyStore ks = KeyStore.getInstance("BKS");
InputStream keyin = v.getResources().openRawResource(R.raw.keystore);
ks.load(keyin, keystorepass);
SSLSocketFactory socketFactory = new SSLSocketFactory(ks);
socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
socket = (SSLSocket)
socketFactory.createSocket(new Socket(ip_address, port), ip_address, port, false);
socket.startHandshake();
printServerCertificate(socket);
printSocketInfo(socket);
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
public static void configureSocketForSSL() {
try {
// Load cert
byte[] der = Configuration.SERVER_CERT.getBytes();
ByteArrayInputStream derInputStream = new ByteArrayInputStream(der);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
String alias = cert.getSubjectX500Principal().getName();
// Create keystore and add to ssl context
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(trustStore, null);
KeyManager[] keyManagers = kmf.getKeyManagers();
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
TrustManager[] trustManagers = tmf.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);
// Add SSL-context and hostname verification
IO.setDefaultSSLContext(sslContext);
IO.setDefaultHostnameVerifier(new RelaxedHostNameVerifier());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Inner class to verify hostname --> Allow all hostname's
*/
public static class RelaxedHostNameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
Works like a charm :)
The other examples are sooo unsafe, because there accept all certs with all hostnames ... so why there using HTTPs at all ?!
I used this Post from Rich Freedman
What is your "Configuration.SERVER_CERT"? I'm trying to get SSL working with a self-signed certificate, but when I tried to use your code block, that's the only part that seemed to barf.
This is just a class for some configurations and static properties, like the public server cert
public class Configuration {
/**
* Server cert
*/
public static final String SERVER_CERT = "-----BEGIN CERTIFICATE-----\n" +
....
"-----END CERTIFICATE-----\n";
Alright, so we're using your configure block to return an ssl context, setting the context on the IO options, and then passing the options in when creating our socket. Still a no-go. Is there a way to turn on logging for the SocketIO portion? We haven't been able to find that either. Here's a snippet of the code we're doing:
` protected SocketFactory(){
try {
IO.Options socketOptions = new IO.Options();
SSLContext sslContext = configureSocketForSSL();
socketOptions.sslContext = sslContext;
socketOptions.hostnameVerifier = new RelaxedHostNameVerifier();
//socketOptions.secure = true;
signalingSocket = IO.socket(signalingURI, socketOptions);
signalingSocket.on("connecting", onConnecting);
signalingSocket.on("connected", onConnected);
signalingSocket.connect();
}
catch(Exception exception){
exception.printStackTrace();
}
}
private static SSLContext configureSocketForSSL() {
try {
// Load cert
byte[] der = SERVER_CERT.getBytes();
ByteArrayInputStream derInputStream = new ByteArrayInputStream(der);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
String alias = cert.getSubjectX500Principal().getName();
// Create keystore and add to ssl context
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(trustStore, null);
KeyManager[] keyManagers = kmf.getKeyManagers();
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
TrustManager[] trustManagers = tmf.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);
return sslContext;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} `
byte[] der = Configuration.SERVER_CERT.getBytes();姹傝В
Fur future reference, IO.setDefaultSSLContext() and IO.setDefaultHostnameVerifier() are not longer available.
The documentation shows how to do this by configuring an OkHttpClient and using the methods IO.setDefaultWebSocketFactory() and IO.setDefaultCallFactory()
Most helpful comment
Works like a charm :)
The other examples are sooo unsafe, because there accept all certs with all hostnames ... so why there using HTTPs at all ?!
I used this Post from Rich Freedman