2014年9月11日木曜日

【Android】HTTPSのWebAPIにAndroidで接続するとエラーになる

Androidで、「https://」ではじまるURLにHTTPリクエストを送って、データを取得したい。

HttpsURLConnectionのクラスを使うらしい。
HttpURLConnectionを使い、「http://」から始まるURLに接続すると、特に困難なくデータが取得できたのに、「https://」の接続先だとうまくいかない。
接続先URLにブラウザで直接アクセスすると、証明書がないからセキュリティ的に怪しいんだけどそれでも接続しちゃっていいの?という画面が表示されて、例外を認める操作をすると接続できるようになる。

Androidが吐くエラーは以下のとおりだった。
09-11 17:16:37.886: W/System.err(3801): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

どうも、サーバーに信用できる証明書がインストールされてないからこの端末からの接続はしたくないんだ!じゃあね!ということらしい。

開発中のアプリの場合、サーバーも開発用のサーバーで証明書なんて無いことが普通なので、これでは困る。

対処法。

サーバーに信用できる証明書がインストールされて無くても無理やりつないでしまえ、という処理を実装するらしい。

参考ページへのリンクを貼っておきます。
http://symfoware.blog68.fc2.com/blog-entry-1165.html

http://blog.kinjouj.net/self-signed-cerificate-https-server-connection-from-java.html

検索の際のキーワード: X509TrustManager オレオレ Android

リンク先が消えた時のため、キモのところだけ、自分のアプリで動いたものをコピペしておきます

---
(AsyncTask継承クラス内の、doInBackground()内)


//////////////////////////////////////////////
//オレオレ証明書によるSSLサーバー接続でもエラーをスルーできるようにする
SSLContext sslcontext = null;

try {
    //証明書情報 全て空を返す
    //証明書情報 全て空を返す
    TrustManager[] tm = {
        new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }//function
            @Override
            public void checkClientTrusted(X509Certificate[] chain,
                    String authType) throws CertificateException {
            }//function
            @Override
            public void checkServerTrusted(X509Certificate[] chain,
                    String authType) throws CertificateException {
            }//function
        }//class
    };
    sslcontext = SSLContext.getInstance("SSL");
    sslcontext.init(null, tm, null);
    //ホスト名の検証ルール 何が来てもtrueを返す
    HttpsURLConnection.setDefaultHostnameVerifier(
        new HostnameVerifier(){
            @Override
            public boolean verify(String hostname,
                    SSLSession session) {
                return true;
            }//function
        }//class
    );
} catch (Exception e) {
    e.printStackTrace();
}//try

////////////////////////////////////////////////////////
//APIに接続
//接続URLを作成
String url_string = "ここにhttps://のURL";

////////////////////////////////////////////////////////
URL url = null;
try {
    url = new URL(url_string);
} catch (MalformedURLException e1) {
}

////////////////////////////////////////////////////////
//HTTPコネクションの作成
HttpsURLConnection connection = null;
try {
    connection = (HttpsURLConnection)url.openConnection();
} catch (IOException e) {
}//try

//オレオレ証明書によるSSLサーバー接続でもエラーをスルーできるようにする
connection.setSSLSocketFactory(sslcontext.getSocketFactory());

////////////////////////////////////////////////////////
//リクエストするパラメータの設定
try {
    connection.setRequestMethod("GET");
} catch (ProtocolException e) {
}//try

////////////////////////////////////////////////////////
//通信の開始
try {
    connection.connect();
} catch (IOException e) {
}//try

---

0 件のコメント:

コメントを投稿