2014-01-19 59 views
9

は、私はこのような要求を使用していました:パイなどApache HttpClientでSSLクライアント証明書を使用するにはどうすればよいですか? Pythonで

requests.put(
       webdavURL, 
       auth=(tUsername, tPassword), 
       data=webdavFpb, 
       verify=False, 
       cert=("/path/to/file.pem", "/path/to/file.key")) 

簡単。

私はApache HttpClientを使ってJavaで同じことを実装する必要があります。 HttpClientを使用してリクエストを行う際にクライアント証明書を渡すにはどうすればよいですか?

答えて

7

主な違いは、Javaでは、通常、鍵と証明書をkey storeに入れてそこから使用することです。あなたがよく言及しているように、多くの人は、httpcomponents clientのように別のライブラリを使いたいと思っています(あなたのpythonの例では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); 
    } 
} 

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> 

私もシンプルに公開しました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); 
      } 
     } 
    } 
} 

そしてここでは、コードの最低額と3番目のバージョンだが、a)のキーストアがない瓶の中に、ディスク上のファイルであるという事実に依存していると、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として挙げることができます。

11

Java HTTPクライアントの代わりにApache HTTPクライアントを使用する場合は、SSLFactoryにキーストアを提供し、DefaultHTTPClientをHTTPSプロトコルで使用するように設定する必要があります。

実例hereがあります。

私は役立つことを願っています。

+0

Java HTTP Clientを使用するためのいくつかのポインタを教えてください。私はApache oneには問題があります。 – Ravi

+5

私は誤っているかもしれませんが、その例では、クライアントを認証するためのクライアント証明書を提供するのではなく、カスタムトラストストア(通常は信頼されていない証明書を信頼するなど)を使用することしかできないようです。 –

+0

これは質問に答えません。これにより、クライアント証明書ではなくカスタムトラストストアが追加されます。 – sstendal

関連する問題