Enterprise Tech Tips
2007
 
 

2007年11月30日のEnterprise Java Technologies Tech Tipsにようこそ。ここでは、Java Platform, Enterprise Edition (Java EE)に含まれているエンタープライズJavaテクノロジやAPIの使用に関するTech Tipを紹介します。

このEnterprise Java Technologies Tech Tipsは、Webログとしてオンラインでも読めるようになりました。

今回のTech Tipでは、GlassFish v2でのSSLの使用を取り上げています。

このTech Tipは、GlassFish v2と呼ばれる、オープン・ソースのJava EE 5リファレンス実装を使って作成されています。GlassFish v2は、GlassFish Community Downloadsページからダウンロードできます。

このコードおよび下記情報の利用には、このライセンス条件が適用されます。

GlassFish v2でのSSLの使用

Kumar Jayanti

ほとんどのエンタープライズ・アプリケーションは、セキュリティ保護された環境で運用する必要があります。Transport Layer Security (TLS)/Secure Sockets Layer (SSL)は、クライアントとサーバ間で交換されるメッセージの認証やメッセージの整合性および機密性の確保に使用できるポイント・ツー・ポイントのセキュリティ保護付きトランスポート機構です。 TLS/SSL (このTech Tipでは単に「SSL」と表記)は、ほとんどのエンタープライズ・アプリケーション環境で求められるセキュリティ保護要件を満たし、広く採用されています。

ただし、SSLでセキュリティ保護されたメッセージ交換に参加するには、サーバがSSLサーバとして有効、すなわち、サーバがSSLサーバ化されていなければなりません。このTech Tipでは、GlassFish v2アプリケーション・サーバをSSLサーバ化する方法を示します。

以降の手順を実施するにあたっては、鍵や証明書などのSSLのいくつかの基本的な概念、およびプロファイルと呼ばれるGlassFish v2の概念を理解する必要があります。

鍵と証明書

鍵および証明書は、SSLの2つの重要な概念です。鍵は、クライアントとサーバ間のトランザクションで信頼とプライバシの確立に使用されます。SSLは、鍵のペアに基づく公開鍵暗号方式を使用しています。鍵のペアは、公開鍵1つと非公開鍵1つで構成されます。データが一方の鍵で暗号化されている場合、そのデータはペアのもう一方の鍵だけで解読できます。

証明書は認証に使用されます。SSLを使用するには、サーバの側で、接続可能な各クライアントIPアドレスごとに証明書が1つ関連付けられている必要があります。証明書はサーバ・サイトの所有者を示し、関連情報を提供します。証明書には、その所有者によって暗号化されたデジタル署名が付いています。認証が重要なサイトの場合、証明書は、よく知られている信頼できる証明書発行局(CA)から購入できます。ただし、認証があまり重要ではない場合は、自己署名の証明書を利用できます。

GlassFish v2のプロファイル

GlassFish v2は、さまざまな使用法プロファイルをサポートしています。各プロファイルは、特定の用途用にアプリケーション・サーバが最適化されるようサーバ構成パラメータをプリセットします。プロファイルには、開発者用(developer)、クラスタ用(cluster)、およびエンタープライズ用(enterprise)の3つがあります。

開発者プロファイルは、開発環境用にGlassFish v2を最適化します。 このことは、構成パラメータが高速起動などをサポートする一方で、ロギングやセッション・レプリケーションなどをサポートしていないことを意味します。クラスタ・プロファイルは、クラスタ作成とセッション・レプリケーションが有効になるように構成パラメータを設定します。クラスタは、1つの論理エンティティとして管理・監視することが可能な一群のGlassFish v2インスタンスです。エンタープライズ・プロファイルは、本稼動環境用にGlassFish v2を最適化します。 ロギングやその他のセキュリティ関連の機能をサポートしています。

GlassFish v2アプリケーション・サーバのSSLサーバ化

GlassFish v2をSSLサーバ化する手順は、アプリケーション・サーバに使用するプロファイルによって異なります。 最初に開発者プロファイルを使用した場合、次にエンタープライズ・プロファイルを使用した場合のSSLサーバ化手順を見てみます。

開発者プロファイルの場合

前述したように、GlassFish v2プロファイルは、特定用途用に構成パラメータをプリセットします。 そうしたパラメータの1つにSecurity Storeがあり、このパラメータは証明書や鍵などのセキュリティおよび信頼関係のアーティファクトの格納方法を示します。開発者プロファイルの場合、Security Store値はJKSに設定されています。この場合、サーバ用の証明書と鍵はJavaキーストア・ファイル(keystore.jks)に、信頼できるCAによって発行された証明書は証明書ファイル(cacerts.jks)に格納されます。

GlassFish v2をインストールすると、サーバ証明書として自動的にデフォルトの自己署名証明書が作成されます。ただし、実際のサイトで認証が重要な場合は、自己署名の証明書をCAから入手したデジタル署名の証明書に置き換えなければなりません。このあと、自己署名の証明書の置換方法、CAからのサーバ証明書の入手方法、サーバ証明書のキーストアへのインポート方法を説明します。

以降の手順では、鍵および証明書の管理ツールとしてkeytoolを使用します。keytoolは、さまざまなバージョンのJava Platform, Standard Edition (Java SE) Development Kit (jdk)に用意されていますが、Java SE 6のkeytoolには必須機能がいくつか追加されています。このため、この手順はjdk 6のkeytoolに基づいています。keytoolの詳細は、JDK Tools and Utilitiesを参照してください。

開発者プロファイルを使ってアプリケーション・サーバを構成した場合のGlassFish v2のSSLサーバ化の手順は次のとおりです。

    1. 次のコマンドを発行して、デフォルトの自己署名証明書を削除します(表示形式の関係上、以降の手順説明ではコマンドを複数の行で示しています)。

             keytool -delete -alias s1as -keystore keystore.jks 
             -storepass <store_passwd>

      <store_passwd>は、キーストア用のパスワード(例: mypass)です。s1asは、GlassFish v2キーストアのデフォルトの別名です。

    2. 次のコマンドを発行し、アプリケーション・サーバ用の新しい鍵のペアを生成します。

            keytool -genkeypair -keyalg <key_alg> 
            -keystore keystore.jks -validity <val_days> -alias s1as 

      <key_alg>は鍵のペアの生成に使用するRSAなどのアルゴリズムで、<val_days>は証明書を有効とみなす日数(例: 365)です。

      このコマンドは、鍵のペアを生成するばかりでなく、自己署名証明書に公開鍵をラップし、別名で指定された新しいキーストア・エントリにその証明書と非公開鍵を格納します。

      証明書の名前は、必ずサイトの完全修飾ホスト名と一致させることが重要です。名前が一致しない場合、サーバに接続するクライアントには、証明書の名前がサイトの名前と一致しないという意味のセキュリティ警告が返されます。デフォルトの自己署名証明書の名前を完全修飾ホスト名と一致させるようにしてください。

    3. 次のコマンドを発行して、Certificate Signing Request (CSR: 証明書署名要求)を生成します。

            keytool -certreq -alias s1as -file <certreq_file> 
            -keystore keystore.jks -storepass <store_passwd>

      <certreq_file>はCSRが格納されているファイル(例: s1as.csr)で、<store_passwd>はそのキーストア用のパスワード(例: changeit)です。

    4. VeriSignなどのCAにCSRを送信します。これに対する応答として、署名入りのサーバ証明書が送られてくるはずです。CAのCA証明書を必ずブラウザにインポートします。CAからの応答で中間証明書が指示されている場合は、その証明書もすべてインポートします。

    5. 「-----BEGIN CERTIFICATE-----」と「-----END CERTIFICATE----」のマーカが入っている、CAからの署名入りサーバ証明書をファイル(この例ではs1as.cert)に格納します。CA証明書と中間CA証明書をすべてダウンロードして、ローカル・ファイルに格納してください。CA証明書と中間CA証明書をブラウザにインポートする方法については、ブラウザのマニュアルを参照してください。CAから、MozillaやInternet ExplorerなどのブラウザにCA証明書をインポートする方法に関する情報が提供されていることがあります。

    6. 元の自己署名証明書を、CAから入手した証明書(s1as.certなどのファイルに格納した証明書)に置き換えます。この置き換えはkeytoolを使って行うことができますが、 複数のステップを伴います。簡単なのは、次のJavaプログラムを実行する方法です。

            import java.io.*;
            import java.security.Key;
            import java.security.KeyStore;
            import java.security.cert.Certificate;
            import java.security.cert.CertificateFactory;
            import java.security.cert.X509Certificate;
            
             
            public class Main {
                public static void main(String[] args) throws Exception {
                   //args[]のエラー検査ロジック省略
                   //CAから入手した署名入り証明書を含むファイル
                  String csrReplyFromCA = args[0];     
                   //GlassFishのkeystore.jksへのパス
                  String keystoreLocation = args[1];   
                   //GlassFishのkeystore.jksに対するパスワード
                  String keystorePassword = args[2];   
                   //置き換える鍵の別名(この例ではs1as)
                  String selfSignedKeyEntry = args[3]; 
                   
                   //署名入り証明書を作成
                  Certificate cert = null;
                  FileInputStream fis = 
                     new FileInputStream(csrReplyFromCA);
                  CertificateFactory cf = 
                     CertificateFactory.getInstance("X.509");
                  cert = cf.generateCertificate(fis);
                   
                   //ここで元のエントリを置き換え
                  char[] passwordChars = 
                     keystorePassword.toCharArray();
                  KeyStore keystore = KeyStore.getInstance("JKS");
                  keystore.load(new FileInputStream(keystoreLocation), 
                     passwordChars);
                  Key key = keystore.getKey(selfSignedKeyEntry,
                     passwordChars);
                  keystore.setKeyEntry(selfSignedKeyEntry, key, 
                     passwordChars, (new Certificate[]{cert}));
                  keystore.store(new FileOutputStream(
                     keystoreLocation), passwordChars);
                }
            }

このプログラムを実行すると、GlassFishキーストア内の証明書s1asは元の自己署名証明書ではなく、CAから入手した証明書になります。元のs1as証明書と、VeriSignから入出した新しいs1as証明書の比較例を次に示します。

元のs1as (自己署名)

Owner: CN=KUMAR, OU=Sun Java System Application Server, O=Sun
Microsystems, L=Santa Clara, ST=California, C=US
Issuer: CN=KUMAR, OU=Sun Java System Application Server, O=Su
n Microsystems, L=Santa Clara, ST=California, C=US
Serial number: 472acd34
Valid from: Fri Nov 02 12:39:40 GMT+05:30 2007 until: Mon Oct
30 12:39:40 GMT+05:30 2017

新しいs1as (CAから入手した署名入り証明書を含む)

Owner: CN=KUMAR, OU=Terms of use at www.verisign.com/cps/test
ca (c)05, OU=Sun Java System Application Server, O=Sun Micros
ystems, L=Santa Clara, ST=California, C=US
Issuer: CN=VeriSign Trial Secure Server Test CA, OU=Terms of
use at https://www.verisign.com/cps/testca (c)05, OU="For Test
Purposes Only. No assurances.", O="VeriSign, Inc.", C=US
Serial number: 1375de18b223508c2cb0123059d5c440
Valid from: Sun Nov 11 05:30:00 GMT+05:30 2007 until: Mon Nov
26 05:29:59 GMT+05:30 2007

ここまでの手順を終えると、GlassFish v2を再起動して、CAによって発行された署名入りサーバ証明書を利用できます。

クラスタ・プロファイルの場合

クラスタ・プロファイルを使ってアプリケーション・サーバを構成した場合のGlassFish v2のSSLサーバ化手順は、developerプロファイルを使用したときの手順と同じです。ただし、この場合は、クラスタ内のすべてのアプリケーション・サーバ・インスタンスで必ず同じサーバの鍵が複製されるようにします。

エンタープライズ・プロファイルの場合

エンタープライズ・プロファイルのSecurity Storeパラメータ値はNSS (Network Security Servicesの略語)になっています。NSSセキュリティ・インフラストラクチャでは、JKSキーストアはなく、このため、デフォルトのGlassFishキーストアは存在しません。

エンタープライズ・プロファイルを使用した場合のGlassFish v2アプリケーション・サーバのSSLサーバ化手順は、 developerプロファイルを使用した場合の手順とほぼ同じですが、違いが2つあります。1つ目の違いは手順の最初のステップに関係しています。JKSキーストアが存在しないため、最初に空のキーストア(keystore.jks)を作成します。2つ目の違いは手順の最後のステップに関係しています。生成された署名入り証明書をJKSキーストアにインポートするのではなく、NSSストアにインポートします。言い替えれば、「開発者プロファイルの場合」と同じ手順を実行しますが、最初に空のキーストアを作成し、ステップ6で次の手順を実行します。

    1. 次のコマンドを発行して、Privacy Enhanced Mail (PEM)形式のキーストアからサーバ証明書用の非公開鍵をエクスポートします。

            keyexport.bat -keyfile serverkey.pem 
            -keystore keystore.jks -storepass changeit -alias s1as 

      このコマンドは、keyexportユーティリティを呼び出します。このkeyexportユーティリティはkeyexportパッケージに含まれており、Project MetroのXWSS downloadsページからダウンロードできます。

      応答として、キーストアのパスワードの入力が求められます。キーストアのパスワードは鍵のパスワードと同じであるため、単にReturn鍵を押せばよいだけです。

      この操作によって、「-----BEGIN PRIVATE KEY-----」と「-----END PRIVATE KEY-----」マーカの間にサーバの非公開鍵の入ったserverkey.pemファイルが作成されます。

    2. CAから入手した、「-----BEGIN CERTIFICATE-----」と「-----END CERTIFICATE-----」マーカを含む署名入り証明書をservercert.pemファイルに付加します。END PRIVATE KEYマーカの直後に付加してください。

    3. serverkey.pemファイルをPKCS#12ファイル(拡張子が.pfxのファイル)に変換します。「PKCS」は、RSA Securityによって考案、公開された一群の公開鍵の暗号化標準を意味します。PKCS#12は、非公開鍵と付随する公開鍵証明書の格納によく使用され、パスワードに基づく対称鍵で保護されるファイル形式の定義です。

      serverkey.pemファイルをPKCS#12ファイルに変換するためのツールはさまざまなものが存在します。 opensslツールはそうしたツールの1つです。以下は、opensslを使ってファイルを変換するコマンド例です。

            openssl pkcs12  -export  -in serverkey.pem -out s1as.pfx

      応答として、エクスポート・パスワードの入力が求められます。「changit」などのパスワードまたはGlassFishのマスタ・パスワードを入力します。

      これでs1as.pfxファイルに、必要な署名入りサーバ証明書と非公開鍵が含まれます。

    4. 次のコマンドを発行し、元の自己署名s1asエントリを削除します。

            certutil -D -n s1as -d $AS_NSS_DB

    5. 次のコマンドを発行し、pk12utilユーティリティを使用して新しいs1as.pfxファイルをNSSストアにインポートします。

            pk12util -i s1as.pfx -d $AS_NSS_DB 

      pk12utilはNSSユーティリティであり、エンタープライズ・プロファイル用GlassFishインストール・テンプレート・ディレクトリにあります。NSSストアに対するPCKS#12ファイルのインポートあるいはエクスポートには、このユーティリティを使用します。

      前述のコマンドに対する応答として、NSSソフト・トークンおよびPKCS#12ファイルに対するパスワードの入力が求められます。それぞれ適切なパスワードを入力してください。インポートが成功したことを示す次のようなメッセージが表示されるはずです。

            pk12util: PKCS12 IMPORT SUCCESSFUL   

さらに次の2つの考慮事項があります。

  • アプリケーション・サーバのプロファイルがenterpriseプロファイルで、サーバの鍵のペアがすでにPKCS#12ファイルに存在する。 s1asという別名のエントリがストアにすでに存在する場合は、「エンタープライズ・プロファイルの場合」の手順に従って手順4を実行して元のエントリを削除すればよいだけです。

          certutil -D -n s1as -d $AS_NSS_DB

    削除したら、手順5に進んで新しいs1as.pfxファイルをNSSストアにインポートします。

          pk12util -i s1as.pfx -d $AS_NSS_DB 

    s1asという別名のエントリがストアに存在しない場合は、単に手順5を実行します。

  • アプリケーション・サーバのプロファイルがdeveloperプロファイルで、サーバの鍵のペアがすでにPKCS#12ファイルに存在する。 この場合は、「エンタープライズ・プロファイルの場合」の説明に従って手順4を実行して、元のs1asエントリを削除すればよいだけです。削除したら、pkcs12importユーティリティを使用して、PCKS#12ファイルをGlassFishキーストアにインポートします。

         pkcs12import.sh -file s1as.pfx -alias s1as 
         -keystore keystore.jks -storepass changeit 
         -pass <exp_password>

    <exp_password>は、PKCS#12ファイルをエクスポートしたときに使用した、changitなどのパスワードです。

    pkcs12importユーティリティはpkcs12importパッケージに含まれており、Project MetroのXWSS downloadsページからダウンロードできます。

関連情報

GlassFishでのSSLについてさらに学習する場合は、SSL and CRL Checking with GlassFish v2をお読みください。

次のリソースもご覧ください。


執筆者について

Kumar JayantiはSun Microsystemsのスタッフ・エンジニアで、Web Technologies and Standardsチームの一員です。現在はXMLおよびWeb Services Security実装のリード役で、最近はGlassFishセキュリティ・モジュールも担当しています。Kumarは2004年の早い頃からずっとWebサービスのセキュリティに関わってきました。インドのIIT Mumbaiで情報科学のM. Tech学位を受け、分散コンピューティングやCORBA、XML、Webサービス、セキュリティなどの分野に関心があります。

開発者支援

Jave EEのプログラミングに関するアドバイスが必要な場合は、開発者向けエキスパートアシスタンス (英語)をお試しください。