UPDATE: As for my original question, it turns out that call to java.security.KeyStore.getCertificate(alias) does actually return X509Certiciate. That wasn't the issue though.
(Bear with me please, I'm new to this certificate stuff.)
I managed to connect to my (self-signed) SSL-enabled server, as long as I don't require authenticated clients. When I do require clientAuth my app yields "routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c"... (also described here)... For some the cure was to switch from BKS to PKCS12, that did not work for me.
So now I am trying to implement my own X509KeyManager
(as suggested here), to hand it to sslContext.init([keyManager], trustManagers, null)
.
If I understand it correctly the sslContext will ask my keyManager(s) for either a certificate chain and/or a private key for a given alias. (Whenever it asks what alias to choose I provide my hard-coded one.)
But according to the X509KeyManager
interface I am supposed to return X509Certificate
. How do I create one using the keystore?
The Android Keystore system lets you store cryptographic keys in a container to make it more difficult to extract from the device. Once keys are in the keystore, they can be used for cryptographic operations with the key material remaining non-exportable.
In order to open an existing KeyStore, click on Menu File > Open > Open KeyStore or use the default keyboard shortcut CTRL+O . A file chooser dialog box will be opened in order to select the desired KeyStore file.
If you are developing for Android, you probably already have these installed. We need to create a Java Key Store (JKS) file that contains our signing information. In generating a JKS for our app, we're actually creating a private key on our computer. This private key is protected by a password that we set.
You can use a KeyStore
with your client certificate for client authentication without explicitly creating a KeyManager
. The code should be something like this:
KeyStore keyStore = KeyStore.getInstance("BKS");
InputStream is = getResources().openRawResource(R.raw.client);
keyStore.load(is, "yourKeyStorePassword".toCharArray());
is.close();
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");
keyManagerFactory.init(keyStore, "yourKeyStorePassword".toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers, null);
Also make sure that your server trusts your client certificate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With