BLOGTIMES
2012/11/06

Amazon RDS に SSL 接続する (JDBC編)

  mysql  aws  ssl 
このエントリーをはてなブックマークに追加

先日、RDS に MySQL Workbench から SSL 接続をしましたが、今日は JDBC からの SSL 接続に挑戦します。
軽くググってみると、証明書を検証しない下記のような接続方法は沢山出てきます。

jdbc:mysql://dbserver:3306/dbname?useSSL=true&requireSSL=true&verifyServerCertificate=false

証明書の検証をしないと SSL の意味がないので、今回は verifyServerCertificate=true にする方法を調べてみました。
以下、作業メモ。

JKS ファイルを作る

Connector/J のリファレンス*1に目を通してみると、サーバ証明書を検証するためには trustCertificateKeyStoreUrl、trustCertificateKeyStoreType、trustCertificateKeyStorePasswordの3つのプロパティを設定してやる必要がありそうです。問題は証明書が格納される trustCertificateKeyStoreType で、前述のリファレンスによれば形式は "JKS" and "PKCS12" でなければなりません。Amazon から配布されている証明書は PEM 形式なので、そのままでは使うことができません。

というわけで、.pem を .jks (JKS形式)に変換してやります。これはJava に付属している keytool を使って下記のように行います。
出力が長いですが、入力する項目は パスワードをいれる部分(2回)と最後の yes と答える部分の合わせて3回だけです。

# wget https://rds.amazonaws.com/doc/mysql-ssl-ca-cert.pem # keytool -keystore amazon.jks -importcert -file mysql-ssl-ca-cert.pem Enter keystore password:(←見えないけどここで123456というパスワードを入力しています。) Re-enter new password:(←見えないけどここで123456というパスワードを入力しています。) Owner: CN=aws.amazon.com/rds/, OU=RDS, O=Amazon.com, L=Seattle, ST=Washington, C=US Issuer: CN=aws.amazon.com/rds/, OU=RDS, O=Amazon.com, L=Seattle, ST=Washington, C=US Serial number: e775b657e21a8128 Valid from: Tue Apr 06 07:44:31 JST 2010 until: Sun Apr 05 07:44:31 JST 2015 Certificate fingerprints: MD5: 36:FD:8B:25:3E:E3:53:FC:E8:82:D1:2E:5C:CC:8C:C6 SHA1: 7F:09:8D:A5:7D:BB:A6:EF:7C:70:D8:CA:4E:49:11:55:7E:89:A7:D3 Signature algorithm name: SHA1withRSA Version: 3 Extensions: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: FF 1F 7C 7E 72 A4 A4 47 F7 8F 48 88 A7 3E D7 38 ....r..G..H..>.8 0010: C9 62 9E DC .b.. ] ] #2: ObjectId: 2.5.29.19 Criticality=false BasicConstraints:[ CA:true PathLen:2147483647 ] #3: ObjectId: 2.5.29.35 Criticality=false AuthorityKeyIdentifier [ KeyIdentifier [ 0000: FF 1F 7C 7E 72 A4 A4 47 F7 8F 48 88 A7 3E D7 38 ....r..G..H..>.8 0010: C9 62 9E DC .b.. ] [CN=aws.amazon.com/rds/, OU=RDS, O=Amazon.com, L=Seattle, ST=Washington, C=US] SerialNumber: [ e775b657 e21a8128] ] Trust this certificate? [no]: yes Certificate was added to keystore

JKSを使って JDBC 接続をする

あとはこんな感じのテストプログラムを作って動かしてみました。
今回はテストなので、前の手順で作成した jks ファイルはクラスパスに放り込んでおいて、クラスローダーからパスを参照します。

MySQLSSLTest.java

import java.net.URL; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public final class MySQLSSLTest { public static void main(final String[] args) throws SQLException { final String server = "rdsdb.ap-northeast-1.rds.amazonaws.com"; final String username = "rds_user"; final String password = "rds_password"; final String jksFile = "amazon.jks"; final String jksPassword = "123456"; URL jks = ClassLoader.getSystemResource(jksFile); final String url = "jdbc:mysql://" + server + "/mysql?useSSL=true" + "&requireSSL=true" + "&verifyServerCertificate=true" + "&trustCertificateKeyStoreUrl=" + jks.toExternalForm() + "&trustCertificateKeyStoreType=JKS" + "&trustCertificateKeyStorePassword=" + jksPassword; Connection con = DriverManager.getConnection(url, username, password); Statement st = con.createStatement(); ResultSet rs = st.executeQuery("SHOW VARIABLES LIKE 'hostname'"); while (rs.next()) { System.out.println(rs.getString(1) + ": " + rs.getString(2)); } rs.close(); st.close(); st = con.createStatement(); rs = st.executeQuery("SHOW STATUS LIKE 'Ssl_cipher'"); while (rs.next()) { System.out.println(rs.getString(1) + ": " + rs.getString(2)); } rs.close(); st.close(); con.close(); } }

あとはプログラムを起動して、こんな感じでホスト名と暗号化の方式が帰ってくればきちんと SSL 接続されています。

hostname: ip-XXX-XXX-XXX-XXX Ssl_cipher: AES128-SHA

トラックバックについて
Trackback URL:
お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/5349
Trackbacks
このエントリにトラックバックはありません
Comments
愛のあるツッコミをお気軽にどうぞ。[policy]
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントはありません
Comments Form

コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。

OpenID を使ってログインすることができます。

Identity URL: Yahoo! JAPAN IDでログイン