2012-03-28 19 views
14

में क्लाइंट सर्टिफिकेट पढ़ना मेरे पास क्लाइंट के रूप में जेबीओएसएस और ब्राउज़र में क्लाइंट सर्वर संचार परिदृश्य है (जावा प्रोग्राम)। प्रारंभ में जब कनेक्शन बनाया जाता है, क्लाइंट अपना प्रमाणपत्र सर्वर पर भेजता है। सर्वर प्रमाण पत्र से ग्राहक की सार्वजनिक कुंजी निकालता है और इस प्रकार संचार जारी रहेगा।
अब मेरा प्रश्न
क्लाइंट से सर्वर से प्रमाणपत्र (.cer) कैसे भेजें?
प्रमाण पत्र कैसे प्राप्त करें और सर्वर में अपनी सार्वजनिक कुंजी निकालें?सर्वलेट

उत्तर

23

ग्राहक से सर्वर से प्रमाणपत्र (.cer) कैसे भेजें?

क्लाइंट प्रमाणपत्र (.cer, .crt, .pem) और इसकी संबंधित निजी कुंजी (.key) को पीकेसीएस # 12 (.p12, .pfx) या जेकेएस (.jks) कंटेनर में पहले पैक किया जाना चाहिए (कीस्टोर)। आपके पास जेकेएस (ट्रस्टस्टोर) के रूप में पैक किए गए सर्वर के सीए प्रमाण पत्र भी होना चाहिए।

उदाहरण HttpClient 3.x का उपयोग कर:

HttpClient client = new HttpClient(); 
// truststore 
KeyStore trustStore = KeyStore.getInstance("JKS", "SUN"); 
trustStore.load(TestSupertype.class.getResourceAsStream("/client-truststore.jks"), "amber%".toCharArray()); 
String alg = KeyManagerFactory.getDefaultAlgorithm(); 
TrustManagerFactory fac = TrustManagerFactory.getInstance(alg); 
fac.init(trustStore); 
// keystore 
KeyStore keystore = KeyStore.getInstance("PKCS12", "SunJSSE"); 
keystore.load(X509Test.class.getResourceAsStream("/etomcat_client.p12"), "etomcat".toCharArray()); 
String keyAlg = KeyManagerFactory.getDefaultAlgorithm(); 
KeyManagerFactory keyFac = KeyManagerFactory.getInstance(keyAlg); 
keyFac.init(keystore, "etomcat".toCharArray()); 
// context 
SSLContext ctx = SSLContext.getInstance("TLS", "SunJSSE"); 
ctx.init(keyFac.getKeyManagers(), fac.getTrustManagers(), new SecureRandom()); 
SslContextedSecureProtocolSocketFactory secureProtocolSocketFactory = new SslContextedSecureProtocolSocketFactory(ctx); 
Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory) secureProtocolSocketFactory, 8443)); 
// test get 
HttpMethod get = new GetMethod("https://127.0.0.1:8443/etomcat_x509"); 
client.executeMethod(get); 
// get response body and do what you need with it 
byte[] responseBody = get.getResponseBody(); 

आप उदाहरण के काम करने में this projectX509Test वर्ग को देखने के मिल सकता है।

HttpClient 4.x विन्यास और वाक्य रचना के साथ थोड़ा अलग होगा:

HttpClient httpclient = new DefaultHttpClient(); 
// truststore 
KeyStore ts = KeyStore.getInstance("JKS", "SUN"); 
ts.load(PostService.class.getResourceAsStream("/truststore.jks"), "amber%".toCharArray()); 
// if you remove me, you've got 'javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated' on missing truststore 
if(0 == ts.size()) throw new IOException("Error loading truststore"); 
// tmf 
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
tmf.init(ts); 
// keystore 
KeyStore ks = KeyStore.getInstance("PKCS12", "SunJSSE"); 
ks.load(PostService.class.getResourceAsStream("/" + certName), certPwd.toCharArray()); 
// if you remove me, you've got 'javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated' on missing keystore 
if(0 == ks.size()) throw new IOException("Error loading keystore"); 
// kmf 
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
kmf.init(ks, certPwd.toCharArray()); 
// SSL 
SSLContext ctx = SSLContext.getInstance("TLS"); 
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 
// socket 
SSLSocketFactory socketFactory = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
Scheme sch = new Scheme("https", 8443, socketFactory); 
httpclient.getConnectionManager().getSchemeRegistry().register(sch); 
// request 
HttpMethod get = new GetMethod("https://localhost:8443/foo"); 
client.executeMethod(get); 
IOUtils.copy(get.getResponseBodyAsStream(), System.out); 

कैसे प्रमाण पत्र प्राप्त और सर्वर में अपने सार्वजनिक कुंजी को निकालने के लिए?

आपको सर्वर को X.509 क्लाइंट प्रमाणपत्र प्रमाणीकरण की आवश्यकता के लिए कॉन्फ़िगर किया जाना चाहिए। फिर एसएसएल हैंडशेक सर्वलेट कंटेनर के दौरान प्रमाण पत्र प्राप्त होगा, इसे ट्रस्टोर के खिलाफ जांचें और इसे अनुरोध विशेषता के रूप में एप्लिकेशन प्रदान करें। एकल प्रमाणपत्र के साथ हमेशा की तरह मामले में आप सर्वलेट वातावरण में इस विधि का उपयोग प्रमाण पत्र को निकालने के लिए कर सकते हैं:

protected X509Certificate extractCertificate(HttpServletRequest req) { 
    X509Certificate[] certs = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate"); 
    if (null != certs && certs.length > 0) { 
     return certs[0]; 
    } 
    throw new RuntimeException("No X.509 client certificate found in request"); 
} 
+0

मैं एक नेट के नजरिए से आ रहा हूँ और ASP.Net 'Page.Request के जावा बराबर की तलाश में। ClientCertificate.Certificate' 'havpServletRequest' में 'javax.servlet.request.X509 प्रमाण पत्र' विशेषता है जो इसके बराबर है? - अगर कोई जानता है ...? –