2010-11-10 33 views
6

Je souhaite accéder par programme à un site nécessitant des certificats Client, que j'ai dans des fichiers PEM. Dans cette application, je ne veux pas les ajouter à mon keystore, utiliser keytool, ou openssl si je peux éviter de le faire. Je dois traiter avec eux directement dans le code.Fichiers de certificat Apache HttpClient et 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(); 

Comment envoyer le certificat avec la demande?

+0

Ou, est-il un autre format de fichier (en plus PEM) qui rendrait cela plus facile à mettre en œuvre? –

Répondre

6

Easiest pourrait bien être d'utiliser le format P12 (bien que les autres fonctionnent bien aussi - juste être prudent avec des lignes supplémentaires en dehors des blocs de base64) et ajouter quelque chose comme:

// 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"); 

Ou bien - utiliser des choses comme

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

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

pour créer à la place ci-dessus à la place. Et plutôt que de compter sur la propriété système - utiliser somethng comme:

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

qui le maintient séparé de keystore.

DW.

+1

Le KeyManagerFactory est la façon dont je devais aller. Je voulais vraiment utiliser un fichier PEM (puisque c'est ce que j'avais). Je n'avais pas réalisé que ce serait si compliqué d'essayer de le convertir à un format différent à la volée. J'ai fini par le convertir au format DER en utilisant openssl. –

-1

Vous pouvez créer un KeyStore de .pem fichiers comme ceci:

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

Ce code n'a pas fonctionné pour moi parce que: (1) les fichiers pem ont '----- BEGIN CERTIFICATE -----' et '----- END CERTIFICATE -----' qui doit être enlevé avant que 'generateCertificates()' puisse être fait; (2) il ne prend pas en compte la clé privée incorporée dans le fichier '.pem'. La solution correcte est disponible ici: http://stackoverflow.com/questions/12501117/programmatically-obtain-keystore-from-pem –