SSLExeptionが出た時の対処法
原因はおそらく自己署名証明かも(じゃないかも)
とりあえずSSLで接続した時にエラーが起きたのでいろいろ
対処法を探していたら解決出来そうなソースコードを見つけたから
今後も使う場面が出てくるかもしれないのでメモとしてコードを記述
import java.security.KeyStore; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.CookieStore; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.ClientContext; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; public class SSLHttpClient { HttpClient httpclient = new DefaultHttpClient(); HttpContext httpcontext = new BasicHttpContext(); StringBuilder sb; SSLHttpClient(StringBuilder _sb) throws Exception { sb = _sb; KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); SSLSocketFactory sf = new MySSLSocketFactory(trustStore); sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); Scheme https = new Scheme("https", sf, 443); httpclient.getConnectionManager().getSchemeRegistry().register(https); httpcontext.setAttribute(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); httpcontext.setAttribute(CoreProtocolPNames.USE_EXPECT_CONTINUE, false); httpcontext.setAttribute(CoreProtocolPNames.HTTP_CONTENT_CHARSET, HTTP.UTF_8); } SSLHttpClient test_get(String url) throws Exception { HttpGet httpget = new HttpGet(url); HttpResponse response = httpclient.execute(httpget, httpcontext); HttpEntity entity = response.getEntity(); if (entity != null) { sb.append(EntityUtils.toString(entity)); } return this; } }
import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.conn.ssl.SSLSocketFactory; public class MySSLSocketFactory extends SSLSocketFactory { SSLContext sslContext = SSLContext.getInstance("TLS"); public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { super(truststore); // 自己署名証明書を受け付けるカスタムSSLContextの準備 TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }; sslContext.init(null, new TrustManager[] { tm }, null); } @Override public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { // カスタムSSLContext経由で生成したSSLソケットを返す。 return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); } @Override public Socket createSocket() throws IOException { // カスタムSSLContext経由で生成したSSLソケットを返す。 return sslContext.getSocketFactory().createSocket(); } }
private String testHttpClient(String req_url){ StringBuilder sb = new StringBuilder(); String jsonString = null; try { SSLHttpClient testHttpClient = new SSLHttpClient(sb).test_get(req_url); jsonString = new String(testHttpClient.sb); return jsonString; } catch (Throwable t) { Log.e("Main", "testHttpClient", t); return null; } } private void hoge(){ JSONObject json = new JSONObject(testHttpClient(req_url)); }
今回はJSONをAPIを叩いてJSONを取得したかったのでJSONObjectに変換して
そこから使うデータを取得しました。
こんな感じでやれば自己署名SSLに対処できるっぽいけどちゃんとソースコードを
理解していないので間違っているかもしれないので、うまく行かない場合は
ごめんなさい。
参考URLは以下のURLでそのままコピペして欲しいデータはJSON形式だったので
そこだけ手を加えました。
http://www.glamenv-septzen.net/view/981