Javaでhttps通信時の証明書検証について †JavaからHTTP接続する際に行われる検証 †https接続する際には、以下の2つの検証が行われる。 (1) 証明書/認証局の検証 ・・・ 有効な証明書か。(信頼できる認証局によって署名された証明書か) 検証を通過させる為のコード †テスト環境等で、まっとうな証明書がインストールされたサーバがない場合、以下のように証明書の検証をスルーする事ができる。 以下は、Android関連の注意換気、ガイド等 /**
* HTTPS通信
*/
private void sendHttpsRequest(String uri, String method, Map param) {
URL urlObj = new URL(uri);
HttpURLConnection http = (HttpsURLConnection) urlObj.openConnection();
// デフォルトのホスト名検証ルールを設定
setDefaultHostnameVerifier();
// 証明書情報を取得
TrustManager[] tm = getTrustManager();
SSLContext sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(null, tm, null);
// 空の証明書情報が設定されたオブジェクトをセット
((HttpsURLConnection) http).setSSLSocketFactory(sslcontext.getSocketFactory());
.
.
.
}
/**
* 信頼する証明書情報を取得する。<br />
* @return 証明書情報
*/
private TrustManager[] getTrustManager() {
TrustManager[] tm = {new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
// 何も検証しない
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
// 何も検証しない
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
// 証明書情報として空を返す(つまり検証を行わない)
return null;
}
} };
return tm;
}
/**
* https通信時のデフォルトのホスト名検証ルールを設定する<br />
*/
private void setDefaultHostnameVerifier() {
// テスト用なので全てtrueを返す(つまり検証を行わない)
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
}
検証を通過させる為のコードを書かない為のテスト環境構築 †上記のコードを書かない為に、できるだけ本番に近い環境構築を行う方法を記載する。 署名用の自己認証局(CA)の作成 †mkdir -p /var/certs/myCA cd /var/certs/myCA mkdir private mkdir newcerts chmod 700 private echo 01>serial touch index.txt sudo openssl req -new -x509 -newkey rsa:2048 -out myca.crt -keyout private/myca.key -days 365 -sha256 ・ いろいろ聞かれるので入力する。 ・ 証明書情報の Organization Name が認証局と一致していなくても署名できるようにする。 †※オリジナルの openssl.cnf からコピーして作成する。 cd /var/certs cp /etc/ssl/openssl.cnf ./ ↓旧メモ [ CA_default ] #dir = ./demoCA dir = ./myCA [ policy_match ] #organizationName = match organizationName = optional ↓新メモ [ca] default_ca = my_ca_default [my_ca_default] new_certs_dir = ./myCA/newcerts database = ./myCA/index.txt serial = ./myCA/serial policy = my_ca_policy default_md = md5 default_days = 365 [my_ca_policy] commonName = supplied countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional emailAddress = optional URLにIPアドレスを指定してアクセスする場合は以下の設定も追記 vim openssl.cnf [ v3_req ] subjectAltName = @alt_names [ alt_names ] IP.1 = XXX.XXX.XXX.XXX # 実際のIPアドレス サーバ秘密鍵 及び 証明書署名要求(CSR)の作成 †# サーバ秘密鍵の作成 openssl genrsa -des3 -out example_com.key 1024 Generating RSA private key, 1024 bit long modulus .++++++ ...............++++++ e is 65537 (0x10001) Enter pass phrase for example_com.key: Verifying - Enter pass phrase for example_com.key: # サーバ秘密鍵のパスフレーズを解除(Apache自動起動用) openssl rsa -in example_com.key -out example_com_nopass.key Enter pass phrase for example_com.key: writing RSA key # サーバ証明書の署名要求(CSR)を作成 openssl req -new -sha256 -key example_com.key -out example_com.csr ・ ・ いろいろ聞かれるので入力する。 (注意!) Common Name、Organization Name は 実際のドメイン名と合わせておく事。(IPアドレスでアクセスする場合はIPアドレスをそのまま入力) ・ ・ 自己認証局で署名 †sudo openssl ca -config ./openssl.cnf -md sha256 -cert myCA/myca.crt -keyfile myCA/private/myca.key -out example_com.crt -in example_com.csr # IPアドレスでアクセスする場合は引数に -extensions v3_req も追加 #sudo openssl ca -config ./openssl.cnf -md sha256 -cert myCA/myca.crt -keyfile myCA/private/myca.key -out 192.168.1.10.crt -in 192.168.1.10.csr -extensions v3_req ・ ・ Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated Apache設定ファイルの編集 †作成した鍵、サーバ証明書のpathを設定する(他のSSL周りの設定は ApacheでSSL(SNI)設定 等を参照 ) SSLCertificateFile /path_to/example_com.crt SSLCertificateKeyFile /path_to/example_com_nopass.key クライアント端末へのインストール †上記で作成したCA証明書(myca.crt)を対象の端末にインストールする。 |