The goal
I'm working on implementing communication with Client-Certificate.
Step 1: Create a PKCS#10 request (CSR) and give it to the my server for signing. The server contacts passes the CSR to the CA, and the CA signs it, and returns a PKCS#7 (with the signed PKCS#10 and the CA's certificate).
Step 2: Create a PKCS#12, store it securely on the Android device
Step 3: Create SSL connection so that the client will be authenticated according to the certificate.
Now, Step 1 works perfectly using SpongyCastle 1.50.0.0, but I'm stuck on the other steps... I'm currently getting an SSL-Handshake exception, but I got the feeling that I should re-think on my implementation.
The question
Does anyone know how to implement the flow? How to create and store whatever's needed for a client side certificate to work well with Android's SSLContext, and how to create such SSLContext?
What I tried so far
My first attempt was to use the KeyChain, but we'd like to avoid the user interaction as described there. My second attempt was to follow Rich Freedman's steps, but I don't know how to create a PKCS#12 from the PKCS#7 and the private key. For persistence, I went over this post, but (a) it's C#, (b) it's unencrypted and (c) I think that the android platform has a better keys persistence mechanism, one that I yet know nothing about. Lastly, this code (for creating a PKCS12 from PEM and PKCS#7) didn't work as well, as I didn't know how to get a CER file and the rest of the things it needs.
Thanks!
Maybe not the best code, but it works, it does not strictly answer all you questions but maybe you will find pieces you can use.
Your flow is good, I'm doing the almost the same thing.
I'm keeping my keys in dynamically created keystore. Additionaly i have keystore with trusted certificates created with openssl tool.
For communication I've used okHttp + retrofit
https://github.com/square/okhttp https://github.com/square/retrofit
Generate
KeyPair
:Generate csr:
Send csr (you may need to convert it to pem format), receive certificate .
Init keystore:
Init truststore:
Add key to keystore (make sure your private key, and certificate match, keystore won't throw exception if they don't, and with okHttp this can cause libssl crashes (only on devices with api below 4.1):
Create okHttpClient with its own
SSLContext
:Look at Nikolay Elenkov blog, you can find many usefull informations with source code as well.
@edit
Post your exception
@edit2
In your case you need to extract your
X509Certificate
from webservice response, store it in keystore with privatekey used for generating csr request and store CA cert in another keystore which will work as truststore. (It can be the same keystore, but it's not recommended).