2009-02-11 3 views
17

मेरे पास एक pkcs12 फ़ाइल है। मुझे https प्रोटोकॉल का उपयोग करके किसी वेबपृष्ठ से कनेक्ट करने के लिए इसका उपयोग करने की आवश्यकता है।जावा में एसएसएल का उपयोग कर एक सुरक्षित वेबसाइट से कैसे कनेक्ट करें pkcs12 फ़ाइल के साथ?

System.setProperty("javax.net.ssl.trustStore", "myTrustStore"); 
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 
System.setProperty("javax.net.ssl.keyStoreType", "pkcs12"); 
System.setProperty("javax.net.ssl.keyStore", "new_cert.p12"); 
System.setProperty("javax.net.ssl.keyStorePassword", "newpass"); 

मैं p12 (PKCS12) फ़ाइल है: मैं कुछ कोड जहां आदेश एक सुरक्षित वेब पेज से कनेक्ट करने में मैं निम्न सिस्टम गुण निर्धारित करने की आवश्यकता बारे में जाना। मुझे बस एक ट्रस्टस्टोर फ़ाइल चाहिए।

keytool -import -file C:/Cacert.der -keystore mytruststore 

अब

openssl.exe pkcs12 -in c:/mykey.p12 -out c:/cert.txt -nokeys -clcerts 

अब प्रमाणपत्र पीईएम फ़ाइल परिवर्तित der को

openssl.exe x509 -in c:/cert.txt -outform DER -out c:/CAcert.der 

अब एक कीस्ट्रोक को der फ़ाइल जोड़ने मेरे पास है:

मैं का उपयोग कर प्रमाण पत्र निकाला ट्रस्टस्टोर, लेकिन जब मैं इसका उपयोग करता हूं, तो मुझे निम्न त्रुटि

मिलती है
Exception in thread "main" java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl) 

अद्यतन: कुछ गुण को दूर करने और केवल "trustStore" स्थापित करने के बाद, "trustStorePassword" और "trustStoreType" संपत्ति, मैं निम्न अपवाद

java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty 

कृपया मदद मिल गया।

+0

यदि आप स्टैक ट्रेस (स्टैक फ्रेम से जानकारी, केवल अपवाद संदेश नहीं) पोस्ट कर सकते हैं तो मैं इसे देख लूंगा। – erickson

+0

जांच करने की एक और बात यह है कि आपका ट्रस्ट स्टोर स्थान सही ढंग से निर्दिष्ट किया गया है; अगर javax.net.ssl.trustStore निर्दिष्ट है लेकिन अस्तित्व में नहीं है, तो फ्लाई पर एक खाली ट्रस्ट स्टोर बनाया गया है। आपका नया त्रुटि संदेश ऐसा लगता है जैसे ऐसा हो सकता है। – erickson

उत्तर

18

एक ऐसी ही स्थिति मैं ऊपर के रूप में इस मुद्दे को हल करने में सक्षम था का सामना कर किसी को भी के लिए:

  1. अपने PKCS12 फ़ाइल से जेनरेट करें इस प्रकार है:

    openssl pkcs12 -in oldpkcs.p12 -out keys -passout pass:tmp 
    openssl pkcs12 -in keys -export -out new.p12 -passin pass:tmp -passout pass:newpasswd 
    
  2. आयात में सर्वर से CA प्रमाणपत्र एक ट्रस्टस्टोर (या तो अपना खुद का, या जावा कीस्टोर $JAVA_HOME/jre/lib/security/cacerts में, पासवर्ड: changeit)।

  3. सेट निम्नलिखित प्रणाली गुण: यूआरएल उर

    System.setProperty("javax.net.ssl.trustStore", "myTrustStore"); 
    System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 
    System.setProperty("javax.net.ssl.keyStoreType", "pkcs12"); 
    System.setProperty("javax.net.ssl.keyStore", "new.p12"); 
    System.setProperty("javax.net.ssl.keyStorePassword", "newpasswd"); 
    
  4. टेस्ट।

सौजन्य @http://forums.sun.com/thread.jspa?threadID=5296333

+0

अपने स्वयं के प्रश्न का उत्तर लिखना और इसे स्वीकार करना अगर आप मुझसे पूछें तो थोड़ा संदिग्ध है। खुद को ऊपर उठाने की तरह थोड़ा (जो निश्चित रूप से संभव नहीं है) – Fredrik

+32

@Fredrik - मेरे लिए बिल्कुल उचित लगता है। मुझे लगता है कि हालांकि अक्सर एफएक्यू में कुछ है। –

4

ऐसा प्रतीत होता है कि आप पीकेसीएस # 12 कुंजी स्टोर से प्रमाण पत्र निकाल रहे हैं और एक नया जावा कुंजी स्टोर (प्रकार "जेकेएस" के साथ) बना रहे हैं। आपको सख्ती से ट्रस्ट स्टोर पासवर्ड प्रदान नहीं करना पड़ता है (हालांकि एक का उपयोग करके आप अपने रूट प्रमाणपत्रों की अखंडता का परीक्षण कर सकते हैं)।

तो, अपने प्रोग्राम को के साथ केवल निम्न SSL गुण सेट के साथ आज़माएं। आपके प्रश्न में दिखाया गया सूची अधिक निर्दिष्ट है और समस्याएं पैदा हो सकती है।

System.setProperty("javax.net.ssl.trustStore", "myTrustStore"); 
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 

इसके अलावा, PKCS # 12 का उपयोग कर फ़ाइल को सीधे रूप में विश्वास की दुकान, काम करना चाहिए जब तक CA प्रमाणपत्र "विश्वसनीय" प्रविष्टि के रूप में पाया जाता है। लेकिन उस स्थिति में, आपको javax.net.ssl.trustStoreType संपत्ति "PKCS12" के रूप में भी निर्दिष्ट करना होगा।

केवल इन गुणों के साथ प्रयास करें। अगर आपको एक ही त्रुटि मिलती है, तो मुझे संदेह है कि आपकी समस्या कुंजी स्टोर नहीं है। यदि यह अभी भी होता है, तो समस्या को कम करने के लिए अपने प्रश्न में अधिक स्टैक ट्रेस पोस्ट करें।


नए त्रुटि, "trustAnchors पैरामीटर, गैर रिक्त होना ही चाहिए" की वजह से एक फ़ाइल जो मौजूद नहीं है के लिए javax.net.ssl.trustStore संपत्ति की स्थापना करने के लिए हो सकता है; अगर फ़ाइल खोला नहीं जा सकता है, तो एक खाली कुंजी स्टोर बनाया गया है, जो इस त्रुटि का कारण बन जाएगा।

+0

मैंने केवल आपके द्वारा निर्दिष्ट गुण सेट किए हैं, अब मुझे निम्न अपवाद मिलता है: "अवैधAlogrithmException: TrustAnchors पैरामीटर गैर-खाली होना चाहिए" – user27221

+0

मैं सिर्फ इस उत्तर का शुक्रिया अदा करना चाहता हूं क्योंकि मुझे नहीं पता था कि "PKCS # 12 का उपयोग करना सीधे ट्रस्ट स्टोर के रूप में फ़ाइल करना चाहिए "और इसने अपना खुद का मुद्दा हल किया – fabien7474

4

यह उपयोग करने के लिए केवल p12 फ़ाइल यह optimazed नहीं कर रहा है, लेकिन यह काम एक उदाहरण है। pkcs12 फ़ाइल जहां ओपनएसएसएल द्वारा उत्पन्न किया गया है। उदाहरण p12 फ़ाइल लोड और इसे से ट्रस्ट क्षेत्र का निर्माण ... यह p12 फ़ाइल से प्रमाणपत्र आउटपुट और

KeyStore ks=KeyStore.getInstance("pkcs12"); 
ks.load(new FileInputStream("client_t_c1.p12"),"c1".toCharArray()); 

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

for (Enumeration<String>t=ks.aliases();t.hasMoreElements();) 
{ 
    String alias = t.nextElement(); 
    System.out.println("@:" + alias); 
    if (ks.isKeyEntry(alias)){ 
     Certificate[] a = ks.getCertificateChain(alias); 
     for (int i=0;i<a.length;i++) 
     { 
      X509Certificate x509 = (X509Certificate)a[i]; 
      System.out.println(x509.getSubjectDN().toString()); 
      if (i>0) 
       jks.setCertificateEntry(x509.getSubjectDN().toString(), x509); 
      System.out.println(ks.getCertificateAlias(x509)); 
      System.out.println("ok"); 
     } 
    } 
} 

System.out.println("init Stores..."); 

KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509"); 
kmf.init(ks, "c1".toCharArray()); 

TrustManagerFactory tmf=TrustManagerFactory.getInstance("SunX509"); 
tmf.init(jks); 

SSLContext ctx = SSLContext.getInstance("TLS"); 
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 
0

मुझे लगता है कि इस लेख पुरानी हो सकती है TrustStore के लिए अच्छा प्रमाणपत्र जोड़ने, लेकिन अभी भी मैं करना चाहते हैं के लिए कैसे अपने स्रोत कोड को सही करने के लिए smithsv से पूछें, इसमें कई गलतियां हैं, मैंने उनमें से अधिकांश को सही करने में कामयाब रहे लेकिन अभी भी नहीं पता कि किस प्रकार की ऑब्जेक्ट x509 हो सकती है। मुझे लगता है कि स्रोत कोड है जैसा कि मुझे लगता है:

import java.io.FileInputStream; 
import java.security.KeyStore; 
import java.security.cert.Certificate; 
import java.util.Enumeration; 

import javax.net.ssl.KeyManagerFactory; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.TrustManagerFactory; 

public class Connection2 { 
    public void connect() { 
     /* 
     * This is an example to use ONLY p12 file it's not optimazed but it 
     * work. The pkcs12 file where generated by OpenSSL by me. Example how 
     * to load p12 file and build Trust zone from it... It outputs 
     * certificates from p12 file and add good certs to TrustStore 
     */ 
     KeyStore ks = KeyStore.getInstance("pkcs12"); 
     ks.load(new FileInputStream(cert.pfx), "passwrd".toCharArray()); 

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

     for(Enumeration t = ks.aliases(); t.hasMoreElements();) { 
      String alias = (String)t.nextElement(); 
      System.out.println("@:" + alias); 
      if(ks.isKeyEntry(alias)) { 
       Certificate[] a = ks.getCertificateChain(alias); 
       for(int i = 0; i == 0;) 
        jks.setCertificateEntry(x509Cert.getSubjectDN().toString(), x509); 

       System.out.println(ks.getCertificateAlias(x509)); 
       System.out.println("ok"); 
      } 
     } 

     System.out.println("init Stores..."); 

     KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 
     kmf.init(ks, "c1".toCharArray()); 

     TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 
     tmf.init(jks); 

     SSLContext ctx = SSLContext.getInstance("TLS"); 
     ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 
    } 
} 
1

यह उदाहरण दिखाता है कि आप मौजूदा सॉकेट के शीर्ष पर एसएसएल कैसे ले सकते हैं, पीकेसीएस # 12 फाइल से क्लाइंट प्रमाण प्राप्त करना ई। यह उचित है जब आपको प्रॉक्सी के माध्यम से अपस्ट्रीम सर्वर से कनेक्ट करने की आवश्यकता होती है, और आप स्वयं द्वारा पूर्ण प्रोटोकॉल को संभालना चाहते हैं।

अनिवार्य रूप से, हालांकि, एक बार आप SSL संदर्भ है, तो आप यह एक HttpsURLConnection, आदि, आदि के लिए आवेदन कर सकते हैं

KeyStore ks = KeyStore.getInstance("PKCS12"); 
InputStream is = ...; 
char[] ksp = storePassword.toCharArray(); 
ks.load(is, ksp); 
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 
char[] kp = keyPassword.toCharArray(); 
kmf.init(ks, kp); 
sslContext = SSLContext.getInstance("SSLv3"); 
sslContext.init(kmf.getKeyManagers(), null, null); 
SSLSocketFactory factory = sslContext.getSocketFactory(); 
SSLSocket sslsocket = (SSLSocket) factory.createSocket(socket, socket 
    .getInetAddress().getHostName(), socket.getPort(), true); 
sslsocket.setUseClientMode(true); 
sslsocket.setSoTimeout(soTimeout); 
sslsocket.startHandshake(); 
5

मैं 50pts सीमा की वजह से टिप्पणी नहीं कर सकता, लेकिन मुझे नहीं लगता कि कि https://stackoverflow.com/a/537344/1341220 में प्रदान किया गया उत्तर सही है। क्या आप वास्तव में वर्णन कर रहे हैं कि कैसे आप सिस्टम डिफ़ॉल्ट truststore में सर्वर प्रमाणपत्र सम्मिलित है:

$JAVA_HOME/jre/lib/security/cacerts, password: changeit) 

यह काम करता है, वास्तव में, लेकिन इसका मतलब है कि तुम सच में अपनी परियोजना के लिए एक ट्रस्ट की दुकान स्थानीय निर्दिष्ट नहीं किया है, बल्कि स्वीकार किए जाते हैं प्रमाणपत्र आपके सिस्टम में सार्वभौमिक रूप से।

आप वास्तव में अपनी खुद की truststore कि यहां आपके द्वारा निर्धारित का उपयोग कभी नहीं:

System.setProperty("javax.net.ssl.trustStore", "myTrustStore"); 
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 
+0

मुझे आपका अंक मिला। लेकिन, मैं सोच रहा हूं, क्या स्टेटमेंट 'System.setProperty' डिफ़ॉल्ट ट्रस्ट स्टोर को बदलता है या नहीं? आपने अपने उत्तर में उल्लेख किया है कि कोड में परिभाषित ट्रस्ट स्टोर का उपयोग करना संभव नहीं है क्योंकि वह पहले से ही डिफ़ॉल्ट का उपयोग कर रहा है। क्या यह वास्तव में सच है? फिर डिफ़ॉल्ट स्टोर बदलने योग्य नहीं होने पर 'System.setProperty'' का बिंदु क्या है? – Salman

0
URL url = new URL("https://test.domain:443"); 
String keyStore = "server.p12" 
String keyStorePassword = "changeit";  
String keyPassword = "changeit";  
String KeyStoreType= "PKCS12";  
String KeyManagerAlgorithm = "SunX509";  
String SSLVersion = "SSLv3";  
public HttpURLConnection getHttpsURLConnection(URL url, String keystore, 
    String keyStorePass,String keyPassword, String KeyStoreType 
    ,String KeyManagerAlgorithm, String SSLVersion) 
    throws NoSuchAlgorithmException, KeyStoreException, 
     CertificateException, FileNotFoundException, IOException, 
     UnrecoverableKeyException, KeyManagementException { 
    System.setProperty("javax.net.debug","ssl,handshake,record"); 

    SSLContext sslcontext = SSLContext.getInstance(SSLVersion); 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerAlgorithm); 
    KeyStore ks = KeyStore.getInstance(KeyStoreType); 
    ks.load(new FileInputStream(keystore), keyStorePass.toCharArray()); 
    kmf.init(ks, keyPassword.toCharArray()); 

    TrustManagerFactory tmf = TrustManagerFactory 
      .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    tmf.init(ks); 
    TrustManager[] tm = tmf.getTrustManagers(); 

    sslcontext.init(kmf.getKeyManagers(), tm, null); 
    SSLSocketFactory sslSocketFactory = sslcontext.getSocketFactory(); 
    HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory); 
    HttpsURLConnection httpsURLConnection = (HttpsURLConnection)uRL.openConnection(); 

    return httpsURLConnection; 
} 
1

निम्न चरणों को आप अपनी समस्या को हल करने के लिए मदद मिलेगी।

चरण: डेवलपर_identity.cer < = ऐप्पल mykey से डाउनलोड करें।p12 = < आपका निजी कुंजी

आदेशों का पालन करने:

openssl x509 -in developer_identity.cer -inform DER -out developer_identity.pem -outform PEM 

    openssl pkcs12 -nocerts -in mykey.p12 -out mykey.pem 

    openssl pkcs12 -export -inkey mykey.pem -in developer_identity.pem -out iphone_dev.p12 

अंतिम p12 है कि हम की आवश्यकता होगी iphone_dev.p12 फ़ाइल और पदबंध है।

इस फ़ाइल का उपयोग अपने पी 12 के रूप में करें और फिर कोशिश करें। यह वास्तव में समाधान है। :)

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