2010-11-10 16 views
6

Me gustaría acceder mediante programación a un sitio que requiere certificados de cliente, que tengo en archivos PEM. En esta aplicación, no quiero agregarlos a mi almacén de claves, usar keytool o openssl si puedo evitar hacerlo. Necesito tratar con ellos directamente en el código.Apache HttpClient y archivos de certificado PEM

HttpClient httpclient = new DefaultHttpClient(); 
    HttpGet httpget = new HttpGet("https://my.secure.site.com/url"); 

    // TODO: Specify ca.pem and client.pem here? 

    HttpResponse response = httpclient.execute(httpget); 
    HttpEntity entity = response.getEntity(); 

    if (entity != null) { 
     entity.consumeContent(); 
    } 

    httpclient.getConnectionManager().shutdown(); 

¿Cómo 'enviaría' el certificado con la solicitud?

+0

O, ¿hay algún otro formato de archivo (además PEM) que haría que esto sea más fácil de implementar? –

Respuesta

6

más fáciles así puede ser utilizar el formato .p12 (aunque los otros trabajan muy bien también - sólo tenga cuidado con líneas adicionales fuera de los bloques de base64) y añadir algo como:

// systems I trust 
System.setProperty("javax.net.ssl.trustStore", "foo"); 
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 

// my credentials 
System.setProperty("javax.net.ssl.keyStoreType", "PKCS12"); 
System.setProperty("javax.net.ssl.keyStore", "cert.p12"); 
System.setProperty("javax.net.ssl.keyStorePassword", "changeit"); 

O, alternativamente, - usar las cosas como

KeyStore ks = KeyStore.getInstance("pkcs12"); 
    ks.load(new FileInputStream(....), "mypassword".toCharArray()); 

    KeyStore jks = KeyStore.getInstance("JKS"); 
    ks.load(... 

para crear arriba sobre la marcha en su lugar. Y en lugar de confiar en la propiedad del sistema, use algo como:

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 
    kmf.init(aboveKeyStore, "changeme".toCharArray()); 
    sslContext = SSLContext.getInstance("SSLv3"); 
    sslContext.init(kmf.getKeyManagers(), null, null); 

que lo mantiene separado del almacén de claves.

DW.

+1

KeyManagerFactory es el camino que necesitaba. Realmente quería usar un archivo PEM (ya que eso es lo que tenía). No me di cuenta de que sería tan complicado tratar de convertirlo a un formato diferente sobre la marcha. Terminé convirtiéndolo a formato DER usando openssl. –

-1

Se puede crear un KeyStore de .pem archivos de este modo:

private KeyStore getTrustStore(final InputStream pathToPemFile) throws IOException, KeyStoreException, 
     NoSuchAlgorithmException, CertificateException { 
    final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 
    ks.load(null); 

    // load all certs 
    for (Certificate cert : CertificateFactory.getInstance("X509") 
      .generateCertificates(pathToPemFile)) { 
     final X509Certificate crt = (X509Certificate) cert; 

     try { 
      final String alias = crt.getSubjectX500Principal().getName(); 
      ks.setCertificateEntry(alias, crt); 
      LOG.info("Added alias " + alias + " to TrustStore"); 
     } catch (KeyStoreException exp) { 
      LOG.error(exp.getMessage()); 
     } 
    } 

    return ks; 
} 
+0

Este código no me funcionó porque: (1) los archivos pem tienen '----- BEGIN CERTIFICATE -----' and '----- END CERTIFICATE -----' que debe eliminarse antes de que 'generateCertificates()' se pueda hacer; (2) no toma en consideración la clave privada incrustada en el archivo '.pem'. La solución correcta está disponible aquí: http://stackoverflow.com/questions/12501117/programmatically-obtain-keystore-from-pem –

Cuestiones relacionadas