2008-12-05 6 views
11

मैं की तरहjarax.net.ssl.keystore के रूप में एक जार में फ़ाइल का उपयोग कैसे करें?

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

कहाँ client.ks है कि मैं चल रहा हूँ जार फ़ाइल में com/मैसेजिंग में संग्रहित एक फाइल है कुछ करने के लिए कोशिश कर रहा हूँ।

जो चीज़ javax.net.ssl.keyStore पढ़ती है वह क्लाइंट.एक्स फ़ाइल के लिए एक मार्ग की उम्मीद कर रही है जो जार में है। मैं फ़ाइल को निकालने और यदि संभव हो तो क्लाइंट की मशीन पर रखूंगा। तो एक जार में एक फाइल का संदर्भ देना संभव है?

यह getPath() वापस शून्य के रूप में काम नहीं करता है। क्या इसे करने का और कोई तरीका है?

+0

शीर्षक भ्रामक है। ऐसा लगता है कि आप पूछ रहे हैं कि क्या आप एक जार फ़ाइल में किसी संसाधन के लिए फ़ाइल संदर्भ प्राप्त कर सकते हैं; System.setProperty कॉल अप्रासंगिक है। –

उत्तर

25

अभी भी कार्यान्वयन पर काम कर रहा है, लेकिन मेरा मानना ​​है कि इनपुटस्ट्रीम के माध्यम से जार से कीस्टोर लोड करना संभव है और स्पष्ट रूप से ट्रस्टस्टोर को प्रोग्रामेटिक रूप से सेट करें (सिस्टम गुणों को सेट करना)। लेख देखें: Setting multiple truststore on the same JVM

यह काम कर रहा है!

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

धन्यवाद! मैं थोड़ी देर के लिए समाधान की तलाश कर रहा हूं, और मैंने जो अन्य चीजें देखी हैं, वह बहुत ही जटिल लगती है :) – jeremija

+0

अच्छा काम, ध्यान दें कि आप कुंजीस्टोर पासवर्ड का दो बार उपयोग कर रहे हैं। कीस्टोर पासवर्ड के रूप में और निजी कुंजी पासफ्रेज के रूप में, और यह हमेशा मामला नहीं है। – muttonUp

+0

मैंने एक नया पैरामीटर जोड़ा, 'स्ट्रिंग कीपैफ्रेज़ "और एक लाइन को keyFactory.init (keyStore, keyPassphrase.toCharArray()) में बदल दिया; – muttonUp

5

आप एक जार फ़ाइल में संसाधन के लिए InputStream प्राप्त कर सकते हैं, लेकिन File नहीं। यदि "चीज" जो आखिरकार कीस्टोर को पढ़ती है तो File या फ़ाइल के पथ की अपेक्षा करता है, तो आपका एकमात्र विकल्प इसे फाइल सिस्टम में निकालना है।

+0

ठीक है, धन्यवाद! इस बीच मैंने यही किया है, और यह ठीक काम करता है; यह सिर्फ साफ नहीं है। – darrickc

1

यहाँ user2529737's answer की एक साफ-संस्करण है, के मामले में यह मदद करता है। इसने अनियंत्रित ट्रस्ट स्टोर सेटअप को हटा दिया है और आवश्यक आयात, कुंजीस्टोर प्रकार और कुंजी पासवर्ड के लिए पैरामीटर जोड़े हैं।

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

(मैं सोच रहा था कि मुझे इसे अपना जवाब बनाना चाहिए या नहीं, लेकिन इसे पढ़ने पर ] (https://meta.stackoverflow.com/a/299524/365237), मैंने इसे स्वयं के रूप में चुना है) – eis

संबंधित मुद्दे