しばらく前に似たようなことをしなければなりませんでした。私は証明書ファイルを持っていて、それをロードしてSSL接続に使用する方法を考え出す必要がありました。うまくいけば、私がしたことがあなたを助けるでしょう。
まず、トラストマネージャーを作成する必要がありました。
public class MyX509TrustManager implements X509TrustManager {
X509TrustManager pkixTrustManager;
MyX509TrustManager() throws Exception {
String certFile = "/certificates/MyCertFile.cer";
Certificate myCert = CertificateFactory.getInstance("X509").generateCertificate(this.getClass().getResourceAsStream(valicertFile));
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, "".toCharArray());
keyStore.setCertificateEntry("myCert", myCert);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX");
trustManagerFactory.init(keyStore);
TrustManager trustManagers[] = trustManagerFactory.getTrustManagers();
for(TrustManager trustManager : trustManagers) {
if(trustManager instanceof X509TrustManager) {
pkixTrustManager = (X509TrustManager) trustManager;
return;
}
}
throw new Exception("Couldn't initialize");
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
pkixTrustManager.checkServerTrusted(chain, authType);
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
pkixTrustManager.checkServerTrusted(chain, authType);
}
public X509Certificate[] getAcceptedIssuers() {
return pkixTrustManager.getAcceptedIssuers();
}
}
その後、トラストマネージャーを使用するソケットファクトリを作成する必要がありました。
public class MySSLProtocolSocketFactory implements SecureProtocolSocketFactory {
private SSLContext sslContext = null;
public MySSLProtocolSocketFactory() {
super();
}
private static SSLContext createMySSLContext() {
try {
MyX509TrustManager myX509TrustManager = new MyX509TrustManager();
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new MyX509TrustManager[] { myX509TrustManager}, null);
return context;
}
catch(Exception e) {
Log.error(Log.Context.Net, e);
return null;
}
}
private SSLContext getSSLContext() {
if(this.sslContext == null) {
this.sslContext = createMySSLContext();
}
return this.sslContext;
}
public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException {
return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
}
public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort, final HttpConnectionParams params) throws IOException {
if(params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
int timeout = params.getConnectionTimeout();
SocketFactory socketFactory = getSSLContext().getSocketFactory();
if(timeout == 0) {
return socketFactory.createSocket(host, port, localAddress, localPort);
}
else {
Socket socket = socketFactory.createSocket();
SocketAddress localAddr = new InetSocketAddress(localAddress, localPort);
SocketAddress remoteAddr = new InetSocketAddress(host, port);
socket.bind(localAddr);
socket.connect(remoteAddr, timeout);
return socket;
}
}
public Socket createSocket(String host, int port) throws IOException {
return getSSLContext().getSocketFactory().createSocket(host, port);
}
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
}
public boolean equals(Object obj) {
return ((obj != null) && obj.getClass().equals(MySSLProtocolSocketFactory.class));
}
public int hashCode() {
return MySSLProtocolSocketFactory.class.hashCode();
}
}
次に、そのソケットファクトリを使用してPOSTを送信しました。
Protocol.registerProtocol("myhttps", new Protocol("myhttps", new MySSLProtocolSocketFactory(), 443));
PostMethod postMethod = new PostMethod("myhttps://some.url.here");
HttpClient client = new HttpClient();
int status = client.executeMethod(postMethod);
私が理解できなかったのは、証明書ファイルを通常のキーストアに追加する方法だけでした。調査中に見つけたすべてのサンプルソースコードは、ソケットファクターを作成し、そのソケットファクトリにプロトコルを登録することを示していました。おそらく、プロトコルを登録せずに、ソケットファクトリを使用して接続を確立する方法があります。私はそれを徹底的に調査していません。私の特定の状況では、特定のプロトコルを作成する必要がありました。うまくいけば、これはあなたの道をさらに進むでしょう。私はそれが少し回り道のように見えることを認めます。最初にやったときも同じように感じました。しかし、これが私がそれを機能させる唯一の方法でした。たぶん他の人がより良い解決策を持っています。