2008-12-05 9 views
11

Je suis en train de faire quelque chose commeComment utiliser un fichier dans un fichier javax.net.ssl.keystore?

URL clientks = com.messaging.SubscriptionManager.class.getResource("client.ks"); 
String path = clientks.toURI().getPath(); 
System.setProperty("javax.net.ssl.keyStore", path); 

Où client.ks est un fichier stocké dans com/messagerie dans le fichier jar que je suis en cours d'exécution. Ce qui lit le fichier javax.net.ssl.keyStore attend un chemin vers le fichier client.ks qui se trouve dans le fichier jar. Je préfère ne pas extraire le fichier et le mettre sur la machine du client si possible. Alors est-il possible de référencer un fichier dans un pot?

Cela ne fonctionne pas car getPath() renvoie la valeur null. Y a-t-il une autre façon de faire cela?

+0

Le titre est trompeur. Il semble que vous demandiez si vous pouvez obtenir une référence de fichier à une ressource dans un fichier jar; l'appel System.setProperty est non pertinent. –

Répondre

25

Toujours en cours d'implémentation, mais je crois qu'il est possible de charger le fichier de clés à partir du fichier jar via InputStream et de paramétrer explicitement le TrustStore par programme (par rapport aux propriétés du système). Voir l'article: Setting multiple truststore on the same JVM

Ça a marché!

InputStream keystoreInput = Thread.currentThread().getContextClassLoader() 
    .getResourceAsStream(<path in jar>/client.ks"); 
InputStream truststoreInput = Thread.currentThread().getContextClassLoader() 
    .getResourceAsStream(<path in jar>/client.ts"); 
setSSLFactories(keystoreInput, "password", truststoreInput); 
keystoreInput.close(); 
truststoreInput.close(); 

private static void setSSLFactories(InputStream keyStream, String keyStorePassword, 
    InputStream trustStream) throws Exception 
{  
    // Get keyStore 
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());  

    // if your store is password protected then declare it (it can be null however) 
    char[] keyPassword = keyStorePassword.toCharArray(); 

    // load the stream to your store 
    keyStore.load(keyStream, keyPassword); 

    // initialize a trust manager factory with the trusted store 
    KeyManagerFactory keyFactory = 
    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());  
    keyFactory.init(keyStore, keyPassword); 

    // get the trust managers from the factory 
    KeyManager[] keyManagers = keyFactory.getKeyManagers(); 

    // Now get trustStore 
    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());  

    // if your store is password protected then declare it (it can be null however) 
    //char[] trustPassword = password.toCharArray(); 

    // load the stream to your store 
    trustStore.load(trustStream, null); 

    // initialize a trust manager factory with the trusted store 
    TrustManagerFactory trustFactory = 
    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());  
    trustFactory.init(trustStore); 

    // get the trust managers from the factory 
    TrustManager[] trustManagers = trustFactory.getTrustManagers(); 

    // initialize an ssl context to use these managers and set as default 
    SSLContext sslContext = SSLContext.getInstance("SSL"); 
    sslContext.init(keyManagers, trustManagers, null); 
    SSLContext.setDefault(sslContext);  
} 
+1

Merci! J'ai été à la recherche de la solution pendant un certain temps, et toutes les autres choses que j'ai vues étaient trop compliquées :) – jeremija

+0

Bon travail, il faut noter cependant que vous utilisez deux fois le keyStorePassword. En tant que mot de passe du keystore et en tant que phrase secrète de la clé privée, ce n'est pas toujours le cas. – muttonUp

+0

J'ai ajouté un nouveau paramètre, 'String keyPassphrase' et changé une ligne à keyFactory.init (keyStore, keyPassphrase.toCharArray()); – muttonUp

5

Vous pouvez obtenir un InputStream pour une ressource dans un fichier jar, mais pas un File. Si la "chose" qui lit en fin de compte le fichier de clés attend un File ou un chemin d'accès à un fichier, votre seule option est de l'extraire vers le système de fichiers.

+0

Ok, merci! C'est ce que j'ai fait entre-temps, et cela fonctionne bien; ce n'est pas aussi propre. – darrickc

1

Voici une version nettoyée de user2529737's answer, au cas où cela serait utile. Il a supprimé la configuration de magasin de confiance superflue et ajouté les importations requises, les paramètres du type de magasin de clés et le mot de passe de clé.

import javax.net.ssl.HttpsURLConnection; 
import javax.net.ssl.KeyManager; 
import javax.net.ssl.KeyManagerFactory; 
import javax.net.ssl.SSLContext; 
import java.io.BufferedReader; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.URL; 
import java.security.KeyStore; 

public class PlainJavaHTTPS2Test { 

    public void setUp() throws Exception { 
     final String KEYSTOREPATH = "clientkeystore.p12"; // or .jks 

     // store password can be null if there is no password 
     final char[] KEYSTOREPASS = "keystorepass".toCharArray(); 

     // key password can be null if there is no password 
     final char[] KEYPASS = "keypass".toCharArray(); 

     try (InputStream storeStream = this.getClass().getResourceAsStream(KEYSTOREPATH)) { 
      setSSLFactories(storeStream, "PKCS12", KEYSTOREPASS, KEYPASS); 
     } 
    } 
    private static void setSSLFactories(InputStream keyStream, String keystoreType, char[] keyStorePassword, char[] keyPassword) throws Exception 
    { 
     KeyStore keyStore = KeyStore.getInstance(keystoreType); 

     keyStore.load(keyStream, keyStorePassword); 

     KeyManagerFactory keyFactory = 
       KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 

     keyFactory.init(keyStore, keyPassword); 

     KeyManager[] keyManagers = keyFactory.getKeyManagers(); 

     SSLContext sslContext = SSLContext.getInstance("SSL"); 
     sslContext.init(keyManagers, null, null); 
     SSLContext.setDefault(sslContext); 
    } 
} 
+0

(Je pensais que je devrais faire sa propre réponse ou non, mais en lisant [cette ] (https://meta.stackoverflow.com/a/299524/365237), j'ai choisi de l'avoir comme sien) – eis

Questions connexes