[java] जावा HTTPS क्लाइंट प्रमाणपत्र प्रमाणीकरण



2 Answers

अन्य उत्तरों क्लाइंट प्रमाणपत्रों को विश्व स्तर पर कॉन्फ़िगर करने का तरीका दिखाते हैं। हालांकि यदि आप एक विशेष कनेक्शन के लिए क्लाइंट कुंजी को प्रोग्रामेटिक रूप से परिभाषित करना चाहते हैं, तो वैश्विक स्तर पर इसे अपने JVM पर चल रहे प्रत्येक एप्लिकेशन में परिभाषित करने के बजाय, आप अपने स्वयं के SSLContext को इस प्रकार कॉन्फ़िगर कर सकते हैं:

String keyPassphrase = "";

KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("cert-key-pair.pfx"), keyPassphrase.toCharArray());

SSLContext sslContext = SSLContexts.custom()
        .loadKeyMaterial(keyStore, null)
        .build();

HttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build();
HttpResponse response = httpClient.execute(new HttpGet("https://example.com"));
Question

मैं एचटीटीपीएस / एसएसएल / टीएलएस के लिए बिल्कुल नया हूं और मैं थोड़ा उलझन में हूं कि प्रमाण पत्र के साथ प्रमाणीकरण करते समय ग्राहकों को वास्तव में क्या पेश करना चाहिए।

मैं एक जावा क्लाइंट लिख रहा हूं जिसे किसी विशेष URL पर डेटा का एक सरल पोस्ट करने की आवश्यकता है। वह हिस्सा ठीक काम करता है, केवल एक ही समस्या यह है कि यह HTTPS पर किया जाना चाहिए। एचटीटीपीएस भाग को संभालने में काफी आसान है (या तो HTTP क्लाइंट के साथ या जावा के अंतर्निर्मित HTTPS समर्थन का उपयोग करके), लेकिन मैं क्लाइंट प्रमाणपत्रों के साथ प्रमाणित करने पर अटक गया हूं। मैंने देखा है कि यहां पहले से ही एक बहुत ही समान प्रश्न है, जिसने अभी तक मेरे कोड के साथ प्रयास नहीं किया है (जल्द ही ऐसा कर देगा)। मेरा वर्तमान मुद्दा यह है कि - जो भी मैं करता हूं - जावा क्लाइंट प्रमाण पत्र के साथ कभी नहीं भेजता है (मैं इसे पीसीएपी डंप के साथ देख सकता हूं)।

मैं जानना चाहता हूं कि प्रमाण पत्र के साथ प्रमाणीकरण करते समय क्लाइंट को क्लाइंट को क्या पेश करना है (विशेष रूप से जावा के लिए - यदि यह बिल्कुल मायने रखता है)? क्या यह एक जेकेएस फ़ाइल है, या पीकेसीएस # 12? उनमें क्या होना चाहिए; बस ग्राहक प्रमाण पत्र, या एक कुंजी? यदि हां, तो कौन सी कुंजी? सभी विभिन्न प्रकार की फाइलों, प्रमाणपत्र प्रकारों और इस तरह के बारे में काफी भ्रम है।

जैसा कि मैंने कहा है कि मैं एचटीटीपीएस / एसएसएल / टीएलएस के लिए नया हूं, इसलिए मैं कुछ पृष्ठभूमि की जानकारी भी सराहना करता हूं (निबंध नहीं होना चाहिए; मैं अच्छे लेखों के लिंक के लिए व्यवस्थित रहूंगा)।




मुझे लगता है कि यहां फिक्स कीस्टोर प्रकार था, pkcs12 (pfx) में हमेशा निजी कुंजी होती है और जेकेएस प्रकार निजी कुंजी के बिना मौजूद हो सकता है। जब तक आप अपने कोड में निर्दिष्ट नहीं करते हैं या ब्राउज़र के माध्यम से प्रमाण पत्र का चयन नहीं करते हैं, तो सर्वर को यह जानने का कोई तरीका नहीं है कि यह दूसरे सिरे पर एक ग्राहक का प्रतिनिधित्व कर रहा है।




मेवेन pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>some.examples</groupId>
    <artifactId>sslcliauth</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>sslcliauth</name>
    <dependencies>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.4</version>
        </dependency>
    </dependencies>
</project>

जावा कोड:

package some.examples;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.InputStreamEntity;

public class SSLCliAuthExample {

private static final Logger LOG = Logger.getLogger(SSLCliAuthExample.class.getName());

private static final String CA_KEYSTORE_TYPE = KeyStore.getDefaultType(); //"JKS";
private static final String CA_KEYSTORE_PATH = "./cacert.jks";
private static final String CA_KEYSTORE_PASS = "changeit";

private static final String CLIENT_KEYSTORE_TYPE = "PKCS12";
private static final String CLIENT_KEYSTORE_PATH = "./client.p12";
private static final String CLIENT_KEYSTORE_PASS = "changeit";

public static void main(String[] args) throws Exception {
    requestTimestamp();
}

public final static void requestTimestamp() throws Exception {
    SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(
            createSslCustomContext(),
            new String[]{"TLSv1"}, // Allow TLSv1 protocol only
            null,
            SSLConnectionSocketFactory.getDefaultHostnameVerifier());
    try (CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(csf).build()) {
        HttpPost req = new HttpPost("https://changeit.com/changeit");
        req.setConfig(configureRequest());
        HttpEntity ent = new InputStreamEntity(new FileInputStream("./bytes.bin"));
        req.setEntity(ent);
        try (CloseableHttpResponse response = httpclient.execute(req)) {
            HttpEntity entity = response.getEntity();
            LOG.log(Level.INFO, "*** Reponse status: {0}", response.getStatusLine());
            EntityUtils.consume(entity);
            LOG.log(Level.INFO, "*** Response entity: {0}", entity.toString());
        }
    }
}

public static RequestConfig configureRequest() {
    HttpHost proxy = new HttpHost("changeit.local", 8080, "http");
    RequestConfig config = RequestConfig.custom()
            .setProxy(proxy)
            .build();
    return config;
}

public static SSLContext createSslCustomContext() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, KeyManagementException, UnrecoverableKeyException {
    // Trusted CA keystore
    KeyStore tks = KeyStore.getInstance(CA_KEYSTORE_TYPE);
    tks.load(new FileInputStream(CA_KEYSTORE_PATH), CA_KEYSTORE_PASS.toCharArray());

    // Client keystore
    KeyStore cks = KeyStore.getInstance(CLIENT_KEYSTORE_TYPE);
    cks.load(new FileInputStream(CLIENT_KEYSTORE_PATH), CLIENT_KEYSTORE_PASS.toCharArray());

    SSLContext sslcontext = SSLContexts.custom()
            //.loadTrustMaterial(tks, new TrustSelfSignedStrategy()) // use it to customize
            .loadKeyMaterial(cks, CLIENT_KEYSTORE_PASS.toCharArray()) // load client certificate
            .build();
    return sslcontext;
}

}



Related