SSL とクライアント認証 (サーバー認証に加えて) を使用して HttpAsyncClient を使用したいと考えています。
いくつか問題がありましたが、最終的に正しい方法を見つけました。その方法を紹介します:
PEM からキーストアを生成します (PEM -> PKCS#12 キーストア -> JKS キーストア)
秘密鍵と公開証明書から PKCS12 キーストアを作成します。
sudo openssl pkcs12 -export -name myservercert -in selfsigned.crt -inkey server.key -out keystore.p12
PKCS12 キーストアを JKS キーストアに変換します。
sudo keytool -importkeystore -destkeystore mykeystore.jks -srckeystore keystore.p12 -srcstoretype pkcs12 -alias myservercert
JKS キーストアの内容を一覧表示します。
sudo keytool -list -v -keystore mykeystore.jks
ローカル JVM はサーバー証明書を信頼する必要があります。自己署名の場合は、cacerts に追加します (信頼できる証明書のリスト。デフォルトのパスワードは「changeit」です)。
sudo keytool -import -alias alias_serv_cert -file /var/tmp/CERT_SERVER.cert -keystore /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.25.x86_64/jre/lib/security/cacerts
クライアントを生成して POST を実行する Java コード:
char[] keystorePass = "MY PASSWORD".toCharArray();
FileInputStream fis = null;
//Loading KEYSTORE in JKS format
KeyStore keyStorePci = KeyStore.getInstance(KeyStore.getDefaultType());
try {
fis = new FileInputStream(keystoreDirectory + keystoreFilename);
keyStorePci.load(fis, keystorePass);
} catch (Exception e) {
LOG.error("Error loading keystore: " + keystoreDirectory+ keystoreFilename);
} finally {
if (fis != null) {
fis.close();
}
}
//Setting JKS keystore in SSL Context (I do not reccomend pass a 3rd argument PrivateKeyStrategy!)
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStorePci, keystorePass).build();
//Creating Async HTTP client with SSL
CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom().setSSLContext(sslcontext).build();
//Executing POST method
try {
httpclient.start();
future = httpclient.execute(httppost, new MyCustomAsyncResultManager(transactionId, transactionToken));
HttpResponse response = future.get();
LOG.info("result: " + response.getStatusLine());
} finally {httpclient.close();}
これがお役に立てば幸いです。