Search code examples
androidsslssl-certificateprivate-keypublic-key

Using .crt instead of a .p12


I am trying to make a connection via my Android client to my server. The server is HTTPS. To make the client connect to the server I used a client.key and client.crt that was signed via the same CA .crt file as the server and converted to a .p12 format. The client is supposed to have the private key and public key. But the client shouldn't have the server private key. The only way to get Android to work is to load in a p12 file from the server into the TrustManagerFactory. But this is not the right way since the private key from the server is inside that file. The TrustManagerFactory doesn't allow me to load in a .crt file.

My question is: How do I load a .crt file into KeyStore instead of the p12 I am using now. Or do I need to use something else then the KeyStore.


Solution

  • Directly from google dev guide working solution for ya:

    // Load CAs from an InputStream
    // (could be from a resource or ByteArrayInputStream or ...)
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    // From https://www.washington.edu/itconnect/security/ca/load-der.crt
    InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
    Certificate ca;
    try {
        ca = cf.generateCertificate(caInput);
        System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
    } finally {
        caInput.close();
    }
    
    // Create a KeyStore containing our trusted CAs
    String keyStoreType = KeyStore.getDefaultType();
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", ca);
    
    // Create a TrustManager that trusts the CAs in our KeyStore
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keyStore);
    
    // Create an SSLContext that uses our TrustManager
    SSLContext context = SSLContext.getInstance("TLS");
    context.init(null, tmf.getTrustManagers(), null);
    
    // Tell the URLConnection to use a SocketFactory from our SSLContext
    URL url = new URL("https://certs.cac.washington.edu/CAtest/");
    HttpsURLConnection urlConnection =
        (HttpsURLConnection)url.openConnection();
    urlConnection.setSSLSocketFactory(context.getSocketFactory());
    InputStream in = urlConnection.getInputStream();
    copyInputStreamToOutputStream(in, System.out);