!!!技術的雑談-JacORBでSSLIOPを試す !!環境 * WindowsXP sp2 * JDK 1.5.0_06 * JacORB-2.2.4 !!目的 * JacORB同士のCORBA通信にSSLIOP(IIOP+SSL)を使用してみる。 !! JacORBの再コンパイル JacORBのbinary配布ファイルはデフォルトでセキュリティー機能がOFFになっているので、SSLIOPを有効にするには再コンパイルする必要があるらしい。 JacORB-2.2.4-source.zipをダウンロードして展開して、 ant clean ant でJacORBを再コンパイルする。 (JacORBを展開したディレクトリ)/lib/jacorb.jarが新しくなっていることを確認する。 CLASSPATH上にIKIAライブラリが存在するか、もしくはJDK1.4.2以上であればSSLIOPが有効なJacORBがビルドされるとの事。 (JDK1.5.0_06を使った限りは再コンパイル時に特に何もしないでJSSEサポートが有効になっているっぽい。) !! キーストアの作成 一般的なJavaのSSL Socketを使った場合と同じようにキーストアを作ってやる必要がある。 C:\temp>keytool -genkey -alias test -keystore test.ks -storepass password 姓名を入力してください。 [Unknown]: Dummy man 【←秘密鍵の持ち主の名前を入力】 組織単位名を入力してください。 [Unknown]: 【←Enterキーのみ。何か入力してもOK。】 組織名を入力してください。 [Unknown]: sample co.ltd. 【←秘密鍵の持ち主の組織名・会社名を入力】 都市名または地域名を入力してください。 [Unknown]: Yokohama 【←都市名】 州名または地方名を入力してください。 [Unknown]: Kanagawa 【←都道府県名】 この単位に該当する 2 文字の国番号を入力してください。 [Unknown]: JP 【←日本ならJP】 CN=Dummy man, OU=Unknown, O=sample co.ltd., L=Yokohama, ST=Kanagawa, C=JP でよろしいですか? [no]: yes 【←yesを入力】 の鍵パスワードを入力してください。 (キーストアのパスワードと同じ場合は RETURN を押してください): 【←Enterキーのみ】 C:\temp> これで、'''C:\temp\test.ks'''というファイル名でキーストアファイルが作られ、中に'''test'''という名前(alias)で秘密鍵と公開鍵が作られる。 キーストアのアクセスパスワードは'''password'''になる。 !! 自己署名 今作った秘密鍵(と公開鍵のペア)を正当なものであることを認める必要がある。 本当は認証機関に送って証明情報を付加してもらうが、今回は実験なので自己署名(オレオレ証明)で済ます。 C:\temp>keytool -selfcert -v -alias test -validity 10000 -keypass password -keystore test.ks キーストアのパスワードを入力してください: password 新しい証明書 (自己署名型): [ [ Version: V1 Subject: CN=Dummy man, OU=Unknown, O=sample co.ltd., L=Yokohama, ST=Kanagawa,C=JP Signature Algorithm: SHA1withDSA, OID = 1.2.840.10040.4.3 Key: Sun DSA Public Key Parameters:DSA p: fd7f5381 1d751229 52df4a9c 2eece4e7 f611b752 3cef4400 c31e3f80 b6512669 455d4022 51fb593d 8d58fabf c5f5ba30 f6cb9b55 6cd7813b 801d346f f26660b7 === 省略 === 83f6d3c5 1ec30235 54135a16 9132f675 f3ae2b61 d72aeff2 2203199d d14801c7 q: 9760508f 15230bcc b292b982 a2eb840b f0581cf5 g: f7e1a085 d69b3dde cbbcab5c 36b857b9 7994afbb fa3aea82 f9574c0b 3d078267 5159578e bad4594f e6710710 8180b449 167123e8 4c281613 b7cf0932 8cc8a6e1 === 省略 === cca4f1be a8519089 a883dfe1 5ae59f06 928b665e 807b5525 64014c3b fecf492a y: 4fe8ee24 4145f19b ecfad301 2eec732e 3b83572a 31979b52 05517a1d 9712fd1e === 省略 === 374de1ac 72ccd5e6 efda191c db938985 5cc352a4 077f2caa ff07ea27 92249bb1 Validity: [From: Thu Jul 24 10:15:09 JST 2008, To: Mon Dec 10 10:15:09 JST 2035] Issuer: CN=Dummy man, OU=Unknown, O=sample co.ltd., L=Yokohama, ST=Kanagawa, C=JP SerialNumber: [ 4887d79d] ] Algorithm: [SHA1withDSA] Signature: 0000: 30 2D 02 14 0B 43 DE C5 79 0D BB C5 EB 32 5B 3B 0-...C..y....2[; === 省略 === 0020: 98 A6 34 09 33 74 F5 93 22 1E EE F3 C7 F9 8D ..4.3t.."...... ] [test.ks を格納中] C:\temp> これで署名がされたっぽい。 '''-validity'''パラメータは証明が有効な日数。(ここでは適当に1万日) 確認。 C:\temp>keytool -list -v -keystore test.ks キーストアのパスワードを入力してください: password キーストアのタイプ: jks キーストアのプロバイダ: SUN キーストアには 1 エントリが含まれます。 別名: test 作成日: 2008/07/24 エントリのタイプ: keyEntry 証明連鎖の長さ: 1 証明書[1]: 所有者: CN=Dummy man, OU=Unknown, O=sample co.ltd., L=Yokohama, ST=Kanagawa, C=JP 実行者: CN=Dummy man, OU=Unknown, O=sample co.ltd., L=Yokohama, ST=Kanagawa, C=JP シリアル番号: 4887d79d 有効日: Thu Jul 24 10:15:09 JST 2008 有効期限: Mon Dec 10 10:15:09 JST 2035 証明書のフィンガープリント: MD5: 5B:97:FC:F4:5B:71:A6:10:DA:21:D5:43:01:68:B8:A9 SHA1: F0:E9:A1:52:D8:57:9A:82:D1:C2:A3:F6:C9:7D:44:51:4C:20:AB:3B ******************************************* ******************************************* C:\temp> 有効期限が2035年とかなっているので大体あっているんでしょう。多分。 !! 実験用アプリの用意 今回は実験用に簡単なServant/Clientを用意する。 (このページ一番下の添付ファイル{{ref JacORB-SSLIOP-Sample01.zip}}) SSLを使わないでも動くようにしてあるので、まずこれが動くことを確認する。 添付の.zipを自分のPCに展開し、eclipseから既存プロジェクトとしてimportする。 (プロジェクトの作成環境はeclipse3.4、JacORBは「D:\JacORB-2.2.4」にインストールされている事を想定したプロジェクトなので、適宜調整してください。) .zip内のlibにあるjacorb-2.2.4.jarは再コンパイルしたjacorb.jarをリネームしたものです。 Servant.batを実行し、Servantを起動。 そのままの状態でClient.batに適当な引数を1つつけて実行するとClient側の標準出力に「Hello 【引数】 !!」と表示される。 ただそれだけのサンプルです。 とりあえずこれがマトモに動くことを確認しておく。 このとき、プロジェクトのルートディレクトリに「ior.txt」というファイルができているので、JacORB付属のdiorコマンドで中身を確認しておく。 [ No configuration properties found for configuration jacorb ] ------IOR components----- TypeId : IDL:idl/Sample:1.0 TAG_INTERNET_IOP Profiles: Profile Id: IIOP Version : 1.2 Host : 10.3.93.27 Port : 1936 Object key (URL): 3151816784/%00%157%17%03%15%16%1F%01$5 Object key (hex): 0x33 31 35 31 38 31 36 37 38 34 2F 00 15 37 17 03 15 16 1F 01 24 35 -- Found 1 Tagged Components-- #0: TAG_ORB_TYPE Type: 1245790976 (JacORB) !! SSLIOPの有効化 SSLIOPを有効化するにはORB.init()の引数の中にSSLを有効化するためのパラメータを入れてやらなくてはならない。 もちろんコーディングで引数を作成しても良いが、パラメータが変更になったりキーストアの場所が変更になったときに再コンパイルが必要になってしまうので、ここでは起動引数のString配列と、System.getProperties()のプロパティーをそのままORB.init()に突っ込む。 (ORB.init()は自分の知らないパラメータやプロパティーは華麗に無視するので問題ない。) JacORBの場合、ORB.init()の引数に「-DORBid=abcd」という値を与えておくと、ORBの初期化の際に「abcd.properties」ファイルの内容を「jacorb.properties」の代わりに使用することができる。 これを利用して同一プログラム内で複数のORBを生成する場合(例:プレーンのORBとSSLIOPのORB)に設定ファイルで分けることができる。 (そもそも、-DORBidの省略時の値が「jacorb」になったいるので、jacorb.propertiesが使用されるというだけの話…。) Servant.batとClient.batの中に「jaco.bat」が含まれている「rem」でコメントアウトされている行が1行ずつある。 それを切り替えてやることでJava側の再コンパイル無しでORBの挙動を切り替えることができる。 「-DORBid」が含まれている側ではJacORBの設定ファイルとしてsample_ssl_servant_orb.propertiesとsample_ssl_client_org.propertiesをそれぞれ使用するようになる。 これによって設定されたORBはCORBA通信(IIOP)の代わりにSSLIOPを使うようになる。 ! sample_ssl_servant_orb.propertiesの内容 # debug logを標準出力へ jacorb.log.default.verbosity=4 # SSLを有効化 jacorb.security.support_ssl=on # SSL Socket Factoryの実装classを指定 jacorb.ssl.socket_factory=org.jacorb.security.ssl.sun_jsse.SSLSocketFactory # SSL Server Socket Factoryの実装classを指定(ServantなのでServer socketが必要なのは当然) jacorb.ssl.server_socket_factory=org.jacorb.security.ssl.sun_jsse.SSLServerSocketFactory # サーバ自身を証明する秘密鍵を持ったキーストアの指定 jacorb.security.keystore=test.ks # キーストアを開く為のキーストア パスワード jacorb.security.keystore_password=password # EstablishTrustInTarget (これらの値は16進数として扱われるので注意) # 多分、サーバ側の証明書が正しいことを確認し、Client側の認証は不要という意味…だと思われる。 jacorb.security.ssl.server.supported_options=20 jacorb.security.ssl.server.required_options=20 ! sample_ssl_client_orb.propertiesの内容 # debug logを標準出力へ jacorb.log.default.verbosity=4 # SSLを有効化 jacorb.security.support_ssl=on # SSL Socket Factoryの実装classを指定 jacorb.ssl.socket_factory=org.jacorb.security.ssl.sun_jsse.SSLSocketFactory # JSSE キーストアを指定 jacorb.security.keystore=test.ks # キーストアのアクセスパスワードを設定 jacorb.security.keystore_password=password # 信頼する署名をキーストアから探す jacorb.security.jsse.trustees_from_ks=on # EstablishTrustInTarget (これらの値は16進数として扱われるので注意) # 多分、サーバ側の証明書が正しいことを確認し、Client側の認証は不要という意味…だと思われる。 jacorb.security.ssl.client.supported_options=20 jacorb.security.ssl.client.required_options=20 SSLでは「サーバ認証」と「クライアント認証」がある。 基本的に「サーバ認証」がONでないSSLというのは聞いたことがない。 サーバ認証とは、サーバが自分自身の証明(=自分が正当なサーバであることを証明する)鍵を持っており、クライアントが自分自身の持っている「信頼できるサーバを表す鍵」とそれを比較することで「自分の意図しないサーバに接続しない」技術のこと。 一般に使われている「https」と同じようなものだと思えばよい。 一方、「クライアント認証」とは、サーバ認証の逆で、サーバ側が「信頼できるクライアントの証明書」を持っており、クライアントの持つ「クライアント証明書」がその中に含まれているかによって「サーバが信頼できると認めたクライアント以外は接続させない」技術のこと。 今回の場合は、サーバもクライアントも「test.ks」というキーストアファイルを自分の証明書、かつ信頼できる相手の証明書リストとして使用している為、ちょっと変といえば変だが、実験だからとりあえずこんなもので良いっぽい。 ちなみに、下記はSSLIOPを使用しているときのIORのdior結果だが、Tagged Componentsの中に「TAG_SSL_SEC_TRANS」があり、SSLを使用する場合のポート番号が示され、一方TAG_INTERNET_IOP ProfilesのPortが0になっていてSSL以外では接続不能になっていることがわかる。 TypeId : IDL:idl/Sample:1.0 TAG_INTERNET_IOP Profiles: Profile Id: IIOP Version : 1.2 Host : 10.3.93.27 Port : 0 Object key (URL): 5726843567/%00%157%16H%06-%18%02%22 Object key (hex): 0x35 37 32 36 38 34 33 35 36 37 2F 00 15 37 16 48 06 2D 18 02 22 -- Found 2 Tagged Components-- #0: TAG_SSL_SEC_TRANS target_supports : Integrity, DetectReplay, DetectMisordering, EstablishTrustInTarget target_requires : EstablishTrustInTarget SSL Port : 1855 #1: TAG_ORB_TYPE Type: 1245790976 (JacORB) このように、JacORBでは外部の.propertiesファイルとORB.init()に与える引数によって、再コンパイル無しにSSLIOP化することが可能です。 !! 本番使用への課題 今の例ではサーバとクライアントで同じ鍵を使っているが、本番ではもちろん違う鍵を使うほうが好ましい。 その場合、 ** サーバ認証の場合:サーバのサーバ証明書を全クライアントに何らかの手段で配布しておき、信頼できるサーバ証明書としておく必要がある。 ** クライアント認証の場合:全クライアントのクライアント証明書をサーバに集め、それらの証明書を信頼できる証明書としておく必要がある。 の作業が必要だが、具体的な方法はOpenSSL関係の説明かJDKのkeytool(.exe)の説明を参照。 !!履歴 2008/07/24 -- 初版 [[技術的雑談]]へ戻る !!突っ込み {{comment}} [[技術的雑談]]へ戻る {{trackback}} [[技術的雑談]]へ戻る