자바의 주요 차이점은 키와 인증서를 보통 key store에 넣고 거기에서 사용하는 것입니다. 여러분이 언급 한 것처럼 사람들은 종종 httpcomponents client을 언급 한 것처럼 (파이썬 예제에서 requests library을 사용하는 것과 같이) 별도의 라이브러리를 사용하려고합니다. 여기
는 앞서 언급 한 라이브러리를 사용하여 키 저장소에서 클라이언트 인증서를 사용하는 예이다 :
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);
}
}
종속 버전
메이븐 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>
test page 클라이언트 인증서를 테스트합니다.
다음은 추가 라이브러리없이 표준 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);
}
}
}
}
그리고 여기에 코드의 최소한의와 세 번째 버전입니다,하지만) 키 스토어가없는 단지 내 디스크에있는 파일이라는 사실에 의존하는, 그리고 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
과 같이 주어질 수있다.
Java HTTP 클라이언트를 사용하기위한 몇 가지 지침을 제공 할 수 있습니까? 나는 아파치 하나에 어려움을 겪고있다. – Ravi
내가 잘못 생각한 것 같습니다.하지만이 예는 클라이언트를 인증하기위한 클라이언트 인증서를 제공하는 대신 사용자 정의 트러스트 스토어 (예 : 일반적으로 신뢰할 수없는 인증서를 신뢰하는 것)를 사용하는 것일뿐입니다. –
이것은 질문에 대답하지 않습니다. 이렇게하면 클라이언트 인증서가 아닌 사용자 지정 트러스트 스토어 만 추가됩니다. – sstendal