3

I write android application. How can I use Certificate in https connection when I initialize certificate from directory file and not from packages?

When I have packages file with password, this code works:

    KeyStore keyStore = KeyStore.getInstance("PKCS12");
    keyStore.load(certificateIs, pass.toCharArray());
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(keyStore, pass.toCharArray());
    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(kmf.getKeyManagers(), trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

But I have certificate initialized from der file:

    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    X509Certificate certificate = (X509Certificate) cf.generateCertificate(certBytes);

I do not know how use this certificate over https connection.

1 Answer 1

2

You seem to be talking about client-certificate authentication (where your Android device is the client).

Firstly, you need the client to have the private key matching the public key in the certificate you're trying to use (that's the whole point, otherwise, it wouldn't authenticated anything). PKCS#12 is one of the usual formats for containing the private key and the certificate. If you only have the certificate in a der file, you probably won't have the private key in it, hence it won't work. It's not quite clear from your question what you do with your certificate variable, with respect to the KeyManagerFactory (if you have a custom X509KeyManager, it should return the private key in its getPrivateKey method, otherwise it won't work).

Secondly, client-certificate authentication is always initiated by the server, so you'd need the server to be set up accordingly too (it seems to be the case already, if your test based on a PKCS#12 keystore works).

Sign up to request clarification or add additional context in comments.

7 Comments

Yes, android application is client, server side implements other company. I have privateKey too (in der). I have certificate + private key. I do not know how can I use this keypar in HttpsURLConnection. with pkcs, I use <code>sc.init(kmf.getKeyManagers(), trustAllCerts, new java.security.SecureRandom());</code> and <code>HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());</code>. But when I have private key and certificate separatly. Probably I must insert privateKey+cert into keyManagerFactory? But I do not know how :(
How is your private key stored?
private key is in pem format and certificate too in pem format. I transform its to der and I use:<br /> X509Certificate certificate = (X509Certificate) cf.generateCertificate(byteCertDerFormat); <br /> privSpec = new PKCS8EncodedKeySpec(bytePKDerFormat); <br /> KeyFactory keyFactory = KeyFactory.getInstance("RSA"); <br /> privKey = (RSAPrivateKey) keyFactory.generatePrivate(privSpec);
Converting your private key + cert into a PKCS#12 file (for example on a machine with OpenSSL) is likely to make things easier. Otherwise, you can probably use the readers from BouncyCastle from their respective classes, but you'd need to know which class has to load each file and that's likely to be more fiddly.
OK, if it's all in PEM format, you might be able to use BouncyCastle's PEMReader (and readObject), but I'd still go for the conversion from the two PEM files into a PKCS#12 file (that's easily done with the openssl command).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.