ヘッダーをスキップ
Oracle® Fusion Middlewareアプリケーション・セキュリティ・ガイド
11gリリース1(11.1.1)
B56235-07
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

27 キーストア・サービスを使用した開発

この章では、アプリケーションの開発時にキーストア・サービスを利用する方法について説明します。

この章では、キーストア・サービスAPIの概要に続いてアプリケーションでサービスを呼び出す際に必要な知識について説明し、サービスの構成方法を説明し、一般的なキーストア操作の例および実行時のキーの取得方法を示します。

この章は、次の項で構成されています。

27.1 キーストア・サービスAPIについて

キーストアは、キーおよび証明書の安全な格納とアクセスに使用します。キーストア・サービスAPIは、キーストアにアクセスして操作を実行するために使用します。

キーストア・サービスの特徴

キーストア・サービスAPIは、次のような重要な機能(作成、更新、削除)を提供します。

KeyStoreに対する操作は、キーストア・サービスで使用されるファイングレイン・アクセス制御モデルを実装するKeyStoreAccessPermissionによって保護されます。

27.2 キーストア・サービスを使用したアプリケーション開発の概要

アプリケーションがキーストア・サービスと連携するように設計するうえで、次の項目に関する知識が役立ちます。

27.3 Javaセキュリティ・ポリシーのパーミッションの設定

Oracle Platform Security Servicesキーストア・プロバイダは、サーバーの起動時に設定されます。プロバイダがファイルベースの場合、データはsystem-jazn-data.xmlに格納されます。

キーストア・サービスでは、次のレベルでのキーの保護をサポートしています。


注意:

  • キーストア・サービスAPIに適切にアクセスするには、ポリシー・ストアでJavaパーミッションを付与する必要があります。

  • キーストア・サービスAPIを呼び出すコードには、コード・ソースのパーミッションが必要です。パーミッションは通常、特定のコードjarに与えられるものであり、アプリケーション全体には与えられません。


この項では、キーストア・オブジェクトへのパーミッションの付与に関するガイドラインおよびいくつかの例を紹介します。


注意:

この例では、アプリケーションのjarファイル名はAppName.jarです。


27.3.1 パーミッション付与のガイドライン

キーストア・サービスでは、Javaパーミッションを使用して、キーストアまたはキー・オブジェクトにパーミッションを付与します。必要なパーミッションのみを付与して、それ以外は付与しないことを強くお薦めします。


警告:

不要なパーミッション、特にすべてのアプリケーション・ストライプやキーストアにアクセスできるパーミッションを付与することは危険であり、お薦めできません。


27.3.2 パーミッション付与例1

キーストア・サービスでは、オブジェクトは階層に格納されます。

アプリケーション・ストライプ -> キーストア -> キー/証明書


関連項目:

キーストア・サービスのオブジェクト階層の詳細は、第11.1.1項を参照してください。


この例では、特定のアプリケーション・ストライプおよびそのストライプ内の特定のキーストア名に対するパーミッションを付与します。

<jazn-policy>
    <grant>
        <grantee>
            <principals>...</principals>
            <!-- This is the location of the jar -->
            <!-- as loaded with the run-time -->
            <codesource>
      <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
            </codesource>
        </grantee>
        <permissions>
            <permission>
               <class>oracle.security.jps.service.keystore.
                      KeyStoreAccessPermission</class>
               <name>stripeName=keystoreapp,keystoreName=ks1,alias=*</name>
              <!-- All actions are granted -->
              <actions>*</actions>
            </permission>
        </permissions>
    </grant>
</jazn-policy>

説明:

  • stripeNameは、これらのパーミッション(ワイルドカード・アクションで示した読取り、書込み、更新および削除パーミッション)を付与するアプリケーション・ストライプの名前(通常はアプリケーション名)です。

  • keystoreNameは、使用中のキーストア名です。

  • aliasはキーストア内のキー別名を示します。


    注意:

    ワイルドカードは、すべての別名に対するパーミッションがアプリケーションに付与されることを意味します。


27.3.3 パーミッション付与例2

この例では、特定のアプリケーション・ストライプ名およびそのすべてのキーストアに対するパーミッションが付与されます。

<jazn-policy>
    <grant>
        <grantee>
            <principals>...</principals>
            <codesource>
      <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
            </codesource>
        </grantee>
        <permissions>
           <permission>
              <class>oracle.security.jps.service.keystore.
                     KeyStoreAccessPermission</class>
              <name>stripeName=keystoreapp,keystoreName=*,alias=*</name>
              <!-- Certain actions are explicitly specified -->
              <!-- Compare to wild-card grant in previous example -->
              <actions>read,write,update,delete</actions>
        </permission>
        </permissions>
    </grant>
</jazn-policy>

27.3.4 パーミッション付与例3

この例では、アプリケーション・ストライプ名内の特定のキー別名およびキーストアに対する読取りパーミッションが付与されます。

<jazn-policy>
    <grant>
        <grantee>
            <principals>...</principals>
            <codesource>
      <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
            </codesource>
        </grantee>
        <permissions>
           <permission>
              <class>oracle.security.jps.service.keystore.
                     KeyStoreAccessPermission</class>
              <name>stripeName=keystoreapp,keystoreName=ks1,alias=orakey</name>
              <actions>read</actions>
        </permission>
        </permissions>
    </grant>
</jazn-policy>

27.4 キーストア・サービスの構成

キーストアの場所とプロバイダ・クラスに関する情報が含まれている構成ファイル内で、キーストア・サービス・インスタンスを定義する必要があります。構成ファイルは、次の場所にあります。

$DOMAIN_HOME/config/fmwconfig

名前は次のとおりです。

27.5 キーストア・サービスAPIの使用

キーストア・サービスは、Oracle WebLogic Server内またはスタンドアロン環境で使用できます。

27.5.1 Java SEアプリケーションでのキーストア・サービスAPIの使用

Java SEアプリケーションでキーストア・サービスAPIを使用するには、次の手順を実行します。

  1. クラスパスを設定します。jps-manifest.jarファイルがそのクラスパスに入っていることを確認します。詳細は、第1.5.3項「シナリオ3: Java SEアプリケーションの保護」の「クラスパスで指定する必要のあるJAR」を参照してください。

  2. ポリシーを設定します。キーストア・サービスAPIにアクセスできるようにするには、参照ポリシー・ストアでアクセス・パーミッションを構成する必要があります。例は、第27.3項「Javaセキュリティ・ポリシーのパーミッションの設定」を参照してください。

  3. JVMコマンド・オプションを設定します。詳細は、次を参照してください。

  4. アプリケーションを実行します。

コマンドライン・オプションは次のとおりです。

  • -Doracle.security.jps.config
    

    構成ファイルjps-config.xmlへのフル・パスを指定します。通常、domain_home/config/fmwconfigディレクトリに存在します。

  • -Djava.security.policy
    

    OPSS/Oracle WebLogic Serverポリシー・ファイルweblogic.policyの場所を指定します。通常、wl_home/server/libディレクトリに存在します。

  • -Dcommon.components.home
    

    Middlewareホームの下にあるoracle_commonディレクトリの場所を指定します。

  • -Djrf.version
    

    環境で使用されるバージョンの値、11.1.1を指定します。

  • -Djava.security.debug=all
    

    デバッグに役立ちます。

27.5.2 Java EEアプリケーションでのキーストア・サービスAPIの使用

Java EEアプリケーションでAPIを使用するには、次の手順を実行します。

  1. 出荷時、jps-config.xmlファイルのキーストア・サービス・プロバイダ・セクションは、次のディレクトリに構成されています。

    $DOMAIN_HOME/config/fmwconfig
    

    必要に応じて、LDAPストアまたはデータベース・ストアへの再関連付けを行ってください。

  2. ポリシーを設定します。キーストア・サービスAPIにアクセスできるようにするには、参照ポリシー・ストアでアクセス・パーミッションを構成する必要があります。例は、第27.3項「Javaセキュリティ・ポリシーのパーミッションの設定」を参照してください。

  3. Oracle WebLogic Serverを起動します。

  4. アプリケーションをデプロイしてテストします。

27.6 キーストア・サービスAPIの使用例

この項では、キーストア・サービスAPIの使用例を紹介します。内容は次のとおりです。

27.6.1 キーストア・サービス管理操作用のJavaプログラム

次のJavaコードは、一般的なキーストア・サービス操作を示しています。

import oracle.security.jps.JpsContext;
import oracle.security.jps.JpsContextFactory;
import oracle.security.jps.JpsException;
import oracle.security.jps.service.keystore.KeyStoreProperties;
import oracle.security.jps.service.keystore.KeyStoreService;
import oracle.security.jps.service.keystore.KeyStoreServiceException;
 
import java.security.AccessController;
import java.security.PrivilegedAction;
 
public class KeyStoreTest {
 
    private static KeyStoreService ks = null;
 
 
    public KeyStoreTest() {
        super();
    }
 
    /*
     * This method performs a non-privileged operation. Either all code
     * in the call stack must have KeyStoreAccessPermission
     * OR
     * the caller must have the KeyStoreAccessPermission only and
     * invoke this operation in doPrivileged block
     */
    public static void doKeyStoreOperation() {
        doOperation();
    }

     /*
     * Since this method performs a privileged operation, only current class or
     * jar containing this class needs KeyStoreAccessPermission
     */
    public static void doPrivilegedKeyStoreOperation() {
        AccessController.doPrivileged(new PrivilegedAction<String>() {
            public String run() {
                doOperation();
                return "done";
            }
        });
    }
 
    private static void doOperation() {
        try {
            ks.deleteKeyStore("keystoreapp", "ks1", null);
        } catch(KeyStoreServiceException e) {
            e.printStackTrace();
        }

 public static void main(String args[]) throws Exception {
 
        try {
            new JpsStartup().start();
            JpsContext ctx = JpsContextFactory.getContextFactory().getContext();
            ks = ctx.getServiceInstance(KeyStoreService.class);
            
            // #1 - this call is in a doPrivileged block
            // #1 - this should succeed.
            doPrivilegedKeyStoreOperation();
 
            // #2 - this will also pass since granted all application
            // code necessary permission
            // NOTE: Since this call is not in a doPrivileged block,
            // this call would have failed if KeyStoreAccessPermission
            // wasn't granted to this class.
 
            /*
            doKeyStoreOperation();
            */
            
        } catch (JpsException je) {
            je.printStackTrace();
        }
 
    }
}

関連項目:

http://docs.oracle.com/javase/6/docs/api/index.htmlにあるキーストアAPIのドキュメント


27.6.2 実行時のキーの読取り

この項では、アプリケーションが実行時にキーストア・アーティファクトにアクセスする方法について説明します。内容は次のとおりです。

27.6.2.1 キーストア・ハンドルの取得

実行時にキーストアにアクセスしてキーと証明書を取得するには、アプリケーションは最初に、キーストア・サービスからキーストア・ハンドルを取得する必要があります。

このタスクの方法は2つあります。

  1. アプリケーション・ストライプおよびキーストア名を個別のパラメータとして明示的に指定し、ハンドルを取得

  2. アプリケーション・ストライプおよびキーストア名を1つのパラメータとして指定し、ハンドルを取得

アプリケーションはいずれのメソッドも自由に使用できます。いずれのメソッドも、まったく同じ方法でキーおよび証明書を取得する動作をします。唯一の相違はキーストアのロード方法です。メソッド1ではOPSS APIを使用するのに対して、メソッド2ではJDKキーストアAPIを使用します。

27.6.2.2 キーストア・アーティファクトのアクセス - メソッド1

次の例では最初のメソッドを示します。ここでは、アプリケーション・ストライプおよびキーストア名は個別のパラメータです。

// First get the KeyStoreService handle from JpsContext

JpsContext ctx = JpsContextFactory.getContextFactory().getContext();
KeyStoreService kss = ctx.getServiceInstance(KeyStoreService.class);
 
// Now get the keystore handle from KeyStoreService. There are two ways to 
// do this:
// Method 1: Explicitly specify application stripe and keystore name as
// separate parameters. In this example, the last parameter is null since
// we are demonstrating a permission-protected keystore. 

java.security.KeyStore keyStore = kss.getKeyStore("keystoreapp", "ks1", null);

// If this keystore is password-protected, provide the keystore password as the
// last parameter.
// java.security.KeyStore.ProtectionParameter pwd = new

java.security.KeyStore.PasswordProtection("password".toCharArray());

// java.security.KeyStore keyStore = kss.getKeyStore("keystoreapp", "ks1", pwd);
 
 
// Method 2: Specify application stripe and keystore name as one parameter
// using KSS URI. The last parameter is the keystore password, which is
// set to null in this example due to permission protected keystore.
// For password-protected keystore, set it to the keystore password.
// Since we are demonstrating Method 1 in this
// example, method 2 is commented out
 
// java.security.KeyStore keyStore kss.getKeyStore("kss://keystoreapp/ks1", null);
 
// Now you have a handle to the JDK KeyStore object. Use this handle to get
// key(s) and/or certificate(s)
 
// Get the private key or secret key associated with this alias. Pass the
// key password as the second parameter. In this case, it is null due to
// permission protected keystore.

Key key = keyStore.getKey("key-alias", null);
 
// Get the certificate associated with this alias

Certificate cert = keyStore.getCertificate("cert-alias");

注意:

次のコードの一部には示されていませんが、loadgetKeygetCertへのコールはすべて権限のある操作で、このためdoPrivileged()ブロックでラップする必要があります。


27.6.2.3 キーストア・アーティファクトのアクセス - メソッド2

次の例では、JDKキーストアURIを使用した、アプリケーション・ストライプおよびキーストア名が1つのパラメータとして指定されるメソッドを示します。

// Create an object with parameters indicating the keystore to be loaded
FarmKeyStoreLoadStoreParameter param = new FarmKeyStoreLoadStoreParameter();
param.setAppStripeName("keystoreapp");
param.setKeyStoreName("ks1");
// The password is set to null in this example since it assumes this is a 
// permission protected keystore.
param.setProtectionParameter(null);
// If the keystore is password protected, use the following lines instead
// java.security.KeyStore.ProtectionParameter pwd = new java.security.KeyStore.PasswordProtection("password".toCharArray());
// param.setProtectionParameter(pwd);
 
// Initialize the keystore object by setting keystore type and provider
java.security.KeyStore keyStore = KeyStore.getInstance("KSS", new FarmKeyStoreProvider());
 
// Load the keystore. There are two ways to do this:
// Method 1: Explicitly specify application stripe and keystore name as
// separate parameters in param object
// keyStore.load(param);
 
// Method 2: Specify application stripe and keystore name as one parameter
// using KSS URI. Since we demonstrate method 2, in this
// example, method 1 is commented out
 
FarmKeyStoreLoadStoreParameter param = new FarmKeyStoreLoadStoreParameter();
param.setKssUri("kss://keystoreapp/ks1");
param.setProtectionParameter(null);
keyStore.load(param);
 
// Now you have a handle to JDK KeyStore object. Use this handle to get
// key(s) and/or certificate(s)
 
// Get the private key or secret key associated with this alias
Key key = keyStore.getKey("key-alias", null);
// Get the certificate associated with this alias
Certificate cert = keyStore.getCertificate("cert-alias");

注意:

次のコードの一部には示されていませんが、loadgetKeygetCertへのコールはすべて権限のある操作で、このため、doPrivileged()ブロックでラップする必要があります。


27.6.3 ポリシー・ストアのセットアップ

この例では、ストアから特定のキーストアへのアクセスに必要とされる適切なパーミッションを持つXMLベースのポリシー・ストア・ファイル(system-jazn-data.xml)を使用して説明しています。このファイルでは、アプリケーション・ストライプとキーストア名の様々な組合せに対するパーミッションを定義します。他の組合せや、ここで定義されたパーミッションを超えたストアへのアクセスは、許可されません。


注意:

この権限付与は、
$DOMAIN_HOME/config/fmwconfig/system-jazn-data.xml
のデフォルトのポリシー・ストアに追加されます。


ここでは、システム・プロパティprojectsrc.homeはJava SEアプリケーションを格納しているディレクトリを指し示すように設定されており、clientApp.jarはサブディレクトリdistにあるアプリケーションjarファイルです。

対応するポリシー付与は、次のようになります。

<grant>
   <grantee>
      <codesource>
         <url>file:${projectsrc.home}/dist/clientApp.jar</url>
      </codesource>
   </grantee>
   <permissions>
      <permission>
         <class>oracle.security.jps.service.keystore.KeyStoreAccessPermission
         </class>
         <name>stripeName=keystoreapp,keystoreName=ks1,alias=*</name>
         <actions>*</actions>
      </permission>
   </permissions>
</grant>

27.6.4 構成ファイル

サンプル構成ファイル(jps-config-jse.xml)を示します。キーストア・サービスのkeystore.file.pathプロパティは、keystores.xmlファイルを含むディレクトリを示しています。


注意:

完全な構成ファイルについては、製品に付属しているデフォルトのファイル($DOMAIN_HOME/config/fmwconfig/jps-config-jse.xml)を参照してください。


<jpsConfig>
 ...
    <serviceInstances>
        <serviceInstance name="keystore_file_instance"
                         provider="keystore_file_provider">
            <property name="keystore.file.path" value="store" />
            <property name="keystore.provider.type" value="file" />
        </serviceInstance>
    </serviceInstances>
 ...
</jpsConfig>

27.6.5 Java SE環境でのキーストア・サービスの使用について

Java SE環境では、次の2つのコールは同等です。

KeyStoreService store = JpsServiceLocator.getServiceLocator().lookup(KeyStoreService.class);

および

KeyStoreService store = JpsContextFactory.getContextFactory().getContext().getServiceInstance
(KeyStoreService.class);

27.7 ベスト・プラクティス

クラスタ環境でストアがファイルベースの場合は、キーストア・サービスAPI上でキーストア・サービスMBean APIを使用して、アプリケーションに対するキーの作成、取得、更新および削除を行います。

ただし、単にキーを読み取るだけの場合は、いずれのAPIも使用できます。