Create SSL-Socket on Android with self-signed cert

2019-03-13 02:54发布

问题:

I'm trying to connect an Android app to a SSL-enabled server, which uses a self-signed certificate. I've already read through dozens of tutorials and the app is now accepting the certificate & connecting to the server, but I never get any data back.

The original code i used to initialize the socket is this:

//passphrase for keystore
char[] keystorePass="password".toCharArray();

//load own keystore (MyApp just holds reference to application context)
KeyStore keyStore=KeyStore.getInstance("BKS");
keyStore.load(MyApp.getStaticApplicationContext().getResources().openRawResource(R.raw.keystore),keystorePass);

//create a factory
TrustManagerFactory     trustManagerFactory=TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);

//get context
SSLContext sslContext=SSLContext.getInstance("TLS");

//init context
sslContext.init(
    null,
    trustManagerFactory.getTrustManagers(), 
    new SecureRandom()
);

//create the socket
Socket socket=sslContext.getSocketFactory().createSocket("hostname",443);
socket.setKeepAlive(true);

Afterwards, the run loop of the receiver thread uses socket.getInputStream() to access the input stream. As long as I use an unencrypted connection, this works without a problem. But the secure connection does not retrieve any data from the socket. I've verified this by adding log messages to the receive loop and even used OpenSSL's s_server to check. I retrieved data from the client, but the client never received anything I sent to it.

As a last test, I tried to open a connection to www.google.com:443 like this:

javax.net.SocketFactory fact=SSLSocketFactory.getDefault();
Socket socket=fact.createSocket(_config.getUri().getHost(), _config.getUri().getPort());

Still the same result, connection works but using the InputStream I receive nothing from the server.

Anybody got any ideas?

EDIT:

I'm currently not allowed to answer my own question, but here's the answer: Well, turns out the problem WAS the receive loop. I relied on InputStream.available() to get the number of bytes to read, but didn't realize it was rather unreliable (always returns 0 for SSL socket). So I switched the receive loop to use the blocking read() instead.

回答1:

As mentioned above: Turns out the problem WAS the receive loop. I relied on InputStream.available() to get the number of bytes to read, but didn't realize it was rather unreliable (always returns 0 for SSL socket). So I switched the receive loop to use the blocking read() instead.



标签: java android ssl