views:

59

answers:

2

I write android application. How can I use Certificate in https connection when I init cert from der file and not from pkcs?

When I have pkcs 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.

A: 

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).

Bruno
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 :(
Peter
How is your private key stored?
Bruno
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);
Peter
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.
Bruno
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).
Bruno
:( application first call registration request, registration is web service, where response are privateKey and cert both in pem format. Other comunication is by using theese certificate. I cannot use command line openssl (its android). ok. I'll write to company who's implement server side, that I need pkcs and no pem. Thanks a lot.
Peter
I'd try BouncyCastle's `PEMReader` then (I think it's available on Android), you should be able to build a `KeyStore` instance and populate it from the objects it returns.
Bruno
A: 

It looks like you could leverage the code here. It sounds a lot like what you are trying to do.

laz