ぬまろぐ

←戻る

Android開発 | 自己証明書を使ってAndroidでHTTPS通信を実装する(2/2)

2017/01/23

Androidアプリ開発で自己証明書を使ってサーバとアプリ間でHTTPS通信を行う場合の実装方法を紹介します。

「自己証明書を使ってAndroidでHTTPS通信を実装する(1/2)」では証明書の発行方法とサーバ側への設定方法を紹介しましたが、ここではAndroidアプリ側への設定方法を紹介します。

CA証明書をassetsフォルダに格納する

生成したCA証明書(cacert.crt)をandroidアプリの「app\src\main\assets」フォルダに格納します。

送信のためのソースコード

AndroidアプリでHTTPS送信のためのソースコードサンプルを以下に記載します。

あまり証明書とは関係ないですが、HTTPヘッダでContent-Lengthを設定しないとボディ部が空で送信されてしまうということに躓いてしまったのでご注意ください。

URL url = new URL("https://xxx");

// assetsに格納したプライベート証明書だけを含む KeyStore を設定
KeyStore ks = KeyStoreUtil.getEmptyKeyStore();
KeyStoreUtil.loadX509Certificate(ks,
mContext.getResources().getAssets().open("cacert.crt"));

// ホスト名の検証ロジックを設定する
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
  @Override
  public boolean verify(String hostname, SSLSession session) {
    if (!hostname.equals(session.getPeerHost())) {
      return false;
    }
    return true;
  }
});

// HttpsURLConnectionの各種設定を行う
trustManager = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManager.init(ks);
SSLContext sslCon = SSLContext.getInstance("TLS");
sslCon.init(null, trustManager.getTrustManagers(), new SecureRandom());
HttpsURLConnection urlCon = (HttpsURLConnection) url.openConnection();
urlCon.setDefaultSSLSocketFactory(sslCon.getSocketFactory());
urlCon.setSSLSocketFactory(sslCon.getSocketFactory());
urlCon.setRequestMethod("POST");
urlCon.setRequestProperty("Content-Length", String.valueOf(body.getBytes(Charset.forName("UTF-8")).length));
urlCon.setRequestProperty("Content-Type", "application/json");
urlCon.setDoOutput(true);
urlCon.setDoInput(true);

// ボディ部の送信
PrintStream ps = new PrintStream(urlCon.getOutputStream(),false,"UTF-8");
ps.print(body);
ps.flush();
ps.close();

// レスポンスの確認
if (urlCon.getResponseCode() != HttpURLConnection.HTTP_OK) {
  throw new IOException("HttpStatus: " + urlCon.getResponseCode());
}
inputStream = new BufferedInputStream(urlCon.getInputStream());
responseArray = new ByteArrayOutputStream();
while ((length = inputStream.read(buff)) != -1) {
  if (length > 0) {
    responseArray.write(buff, 0, length);
  }
}
return responseArray.toString();