栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在Apache HttpClient中使用SSL客户端证书?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在Apache HttpClient中使用SSL客户端证书?

我认为主要区别在于,在Java中,通常将密钥和证书放在密钥存储区中,然后从那里使用它。就像您提到的那样,人们经常希望为此使用单独的库,例如提到的httpcomponents客户端(就像您在python示例中使用请求库一样)。

这是一个使用前面提到的库使用密钥库中的客户机证书的示例:

import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.HttpClients;import org.apache.http.ssl.SSLContexts;import org.apache.http.util.EntityUtils;import org.junit.Test;import javax.net.ssl.SSLContext;import java.io.InputStream;import java.security.KeyStore;import static org.junit.Assert.assertEquals;import static org.junit.Assert.assertNotNull;public class MyClientCertTest {    private static final String KEYSTOREPATH = "/clientkeystore.jks"; // or .p12    private static final String KEYSTOREPASS = "keystorepass";    private static final String KEYPASS = "keypass";    KeyStore readStore() throws Exception {        try (InputStream keyStoreStream = this.getClass().getResourceAsStream(KEYSTOREPATH)) { KeyStore keyStore = KeyStore.getInstance("JKS"); // or "PKCS12" keyStore.load(keyStoreStream, KEYSTOREPASS.toCharArray()); return keyStore;        }    }    @Test    public void readKeyStore() throws Exception {        assertNotNull(readStore());    }    @Test    public void performClientRequest() throws Exception {        SSLContext sslContext = SSLContexts.custom()     .loadKeyMaterial(readStore(), KEYPASS.toCharArray()) // use null as second param if you don't have a separate key password     .build();        HttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build();        HttpResponse response = httpClient.execute(new HttpGet("https://slsh.iki.fi/client-certificate/protected/"));        assertEquals(200, response.getStatusLine().getStatusCode());        HttpEntity entity = response.getEntity();        System.out.println("----------------------------------------");        System.out.println(response.getStatusLine());        EntityUtils.consume(entity);    }}

Maven pom用于依赖版本:

<?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>com.acme</groupId>    <artifactId>httptests</artifactId>    <version>0.0.1-SNAPSHOT</version>    <properties>        <maven.compiler.source>1.8</maven.compiler.source>        <maven.compiler.target>1.8</maven.compiler.target>    </properties>    <dependencies>        <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version>        </dependency>        <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope>        </dependency>    </dependencies>    <build>        <plugins> <plugin>     <groupId>org.apache.maven.plugins</groupId>     <artifactId>maven-surefire-plugin</artifactId>     <version>2.9</version>     <!-- this is not needed, but useful if you want to debug what's going          on with your connection -->     <configuration>         <argLine>-Djavax.net.debug=all</argLine>     </configuration> </plugin>        </plugins>    </build></project>

我还发布了一个简单的测试页,用于测试客户端证书。


只是为了证明它是可以做到的,下面是一个示例,该示例仅使用标准Java API来使用客户端证书,而没有额外的库。

import org.junit.Test;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 {    @Test    public void testJKSKeyStore() throws Exception {        final String KEYSTOREPATH = "clientkeystore.jks";        final char[] KEYSTOREPASS = "keystorepass".toCharArray();        final char[] KEYPASS = "keypass".toCharArray();        try (InputStream storeStream = this.getClass().getResourceAsStream(KEYSTOREPATH)) { setSSLFactories(storeStream, "JKS", KEYSTOREPASS, KEYPASS);        }        testPlainJavaHTTPS();    }    @Test    public void testP12KeyStore() throws Exception {        final String KEYSTOREPATH = "clientkeystore.p12";        final char[] KEYSTOREPASS = "keystorepass".toCharArray();        final char[] KEYPASS = "keypass".toCharArray();        try (InputStream storeStream = this.getClass().getResourceAsStream(KEYSTOREPATH)) { setSSLFactories(storeStream, "PKCS12", KEYSTOREPASS, KEYPASS);        }        testPlainJavaHTTPS();    }    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);    }    public void testPlainJavaHTTPS() throws Exception {        String httpsURL = "https://slsh.iki.fi/client-certificate/protected/";        URL myUrl = new URL(httpsURL);        HttpsURLConnection conn = (HttpsURLConnection)myUrl.openConnection();        try (InputStream is = conn.getInputStream()) { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String inputLine; while ((inputLine = br.readLine()) != null) {     System.out.println(inputLine); }        }    }}

这是代码最少的第三个版本,但是它依赖于以下事实:a)密钥库是磁盘上的文件,而不是jar中的文件,并且b)密钥密码 必须 与密钥库密码相同。

import org.junit.BeforeClass;import org.junit.Test;import java.net.URL;import java.io.*;import javax.net.ssl.HttpsURLConnection;public class PlainJavaHTTPSTest {    @BeforeClass    public static void setUp() {        System.setProperty("javax.net.ssl.keyStore", "/full/path/to/clientkeystore-samepassword.jks");        System.setProperty("javax.net.ssl.keyStorePassword", "keystorepass");    }    @Test    public void testPlainJavaHTTPS() throws Exception {        String httpsURL = "https://slsh.iki.fi/client-certificate/protected/";        URL myUrl = new URL(httpsURL);        HttpsURLConnection conn = (HttpsURLConnection)myUrl.openConnection();        try (InputStream is = conn.getInputStream()) { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String inputLine; while ((inputLine = br.readLine()) != null) {     System.out.println(inputLine); }        }    }}

当然,也可以将上面在代码中设置的属性指定为启动参数

-Djavax.net.ssl.keyStore=/full/path/to/clientkeystore-samepassword.jks
-Djavax.net.ssl.keyStorePassword=keystorepass



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/449987.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号