ヘッダーをスキップ
Oracle Database JDBC開発者ガイド
11gリリース2(11.2)
B56281-01
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

9 JDBCクライアント側セキュリティ機能

この章では、Oracle Java Database Connectivity(JDBC)Oracle Call Interface(OCI)ドライバとJDBC Thinドライバによるログイン認証、データ暗号化およびデータ整合性のサポートについて、特にOracle Advanced Securityオプションの機能の観点から説明します。

以前Advanced Networking Option(ANO)またはAdvanced Security Option(ASO)と呼ばれていたOracle Advanced Securityは、業界標準に基づくデータ暗号化、データ整合性、サード・パーティ認証、シングル・サインオンおよびアクセス認可の機能を提供します。11gリリース2(11.2)では、JDBC OCIドライバとJDBC Thinドライバの両方で、Oracle Advanced Securityの機能をすべてサポートしています。以前のリリースのJDBCドライバでは、ASOの一部の機能をサポートしていませんでした。


注意:

サーバー側内部ドライバを介したすべての通信が完全にサーバー内で行われるため、この説明はサーバー側内部ドライバには関係しません。

この章の内容は次のとおりです。

Oracle Advanced Securityのサポート

Oracle Advanced Securityでは、次のセキュリティ機能をサポートしています。


ヒント:

『Oracle Database Advanced Security管理者ガイド』

JDBC OCIドライバによるOracle Advanced Securityのサポート

JDBC OCIドライバを使用している場合は、Oracleクライアントがインストールされているコンピュータから実行していることが想定されるため、Oracle Advanced Securityと組込みサード・パーティ機能のサポートは、Oracleクライアントによって提供されるサポートとほとんど同じです。Advanced Security機能が使用されているかどうかは、クライアント・コンピュータのsqlnet.oraファイル内の、関連する設定の内容によって判断できます。

Oracle Database 11gリリース1 (11.1)以上では、パスワードを入力しないでデータベースに接続しようとすると、JDBC OCIドライバは外部認証を使用しようとします。JDBC OCIドライバを使用して、パスワードを入力しないでデータベースに接続する例を次に示します。

SSL認証

例9-1は、SSL認証を使用してデータベースに接続する例です。

例9-1 SSL認証を使用したデータベースへの接続

import java.sql.*;
import java.util.Properties;
 
public class test
{
    public static void main( String [] args ) throws Exception
    {
        String url = "jdbc:oracle:oci:@"
         +"(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=stadh25)(PORT=1529))"
         +"(CONNECT_DATA=(SERVICE_NAME=mydatabaseinstance)))";
        Driver driver = new oracle.jdbc.OracleDriver();
        Properties props = new Properties();
        Connection conn = driver.connect( url, props );
        conn.close();
    }
}

データソースの使用

例9-2は、データソースを使用してデータベースに接続する例です。

例9-2 データソースを使用したデータベースへの接続

import java.sql.*; 
import javax.sql.*; 
import java.util.Properties; 
import oracle.jdbc.pool.*; 
 
public class testpool { 
    public static void main( String args ) throws Exception 
    { String url = "jdbc:oracle:oci:@" +"(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=stadh25)(PORT=1529))"
 +"(CONNECT_DATA=(SERVICE_NAME=mydatabaseinstance)))"; 
    OracleConnectionPoolDataSource ocpds = new OracleConnectionPoolDataSource(); 
    ocpds.setURL(url); 
    PooledConnection pc = ocpds.getPooledConnection(); 
    Connection conn = pc.getConnection(); 
    } 
    }

JDBC ThinドライバによるOracle Advanced Securityのサポート

JDBC Thinドライバでは、Oracleクライアントがインストールされていること、またはsqlnet.oraファイルが存在していることを前もって想定できません。したがって、Javaアプローチを使用してOracle Advanced Securityをサポートします。Oracle Advanced Securityを実装するJavaクラスは、ojdbc5.jarファイルおよびojdbc6.jarファイルに含まれています。暗号化と整合性のためのセキュリティ・パラメータは、通常のようにsqlnet.ora内に設定されるのではなく、JavaのPropertiesオブジェクトか、またはシステム・プロパティを使用して設定されます。

ログイン認証のサポート

JDBCを介した基本ログイン認証では、Oracleサーバーへの他のログイン方法と同様に、ユーザー名とパスワードが要求されます。Javaプロパティ・オブジェクトを使用するか、またはgetConnectionメソッドを直接コールして、ユーザー名とパスワードを指定します。これは、使用しているクライアント側Oracle JDBCドライバにかかわらず適用されますが、サーバー側内部ドライバを使用している場合には、特殊な直接接続を使用しており、ユーザー名またはパスワードを要求しないため、関係ありません。

11gリリース1 (11.1)以降、Oracle JDBC Thinドライバには、ユーザーを認証する方式としてチャレンジ・レスポンス・プロトコルが実装されています。

厳密認証のサポート

Oracle Advanced Securityでは、Oracle Databaseユーザーに対する外部認証が可能です。外部認証には、RADIUS、KERBEROS、証明書ベースの認証、トークン・カードおよびスマート・カードなどが使用されます。この認証方法は、厳密認証と呼ばれます。Oracle JDBCドライバでサポートしている厳密認証方法は次のとおりです。

OS認証のサポート

オペレーティング・システム(OS)認証を使用すると、Oracleで、オペレーティング・システムにユーザー認証の制御を渡すことができます。ユーザーは、データベース内のOSユーザー名を認証することによってデータベースに接続できます。OS認証で十分であると想定されるため、アカウントにはパスワードが関連付けられていません。つまり、サーバーはクライアントOSに認証を委任します。この状態にするには次の手順を実行する必要があります。

ローカル・データベース・サーバーから接続を試みると、OSユーザー名がOracleサーバーに渡されます。ユーザー名が認識されると接続が許可され、それ以外の場合、接続は拒否されます。

Linuxの構成手順

Linux上でOS認証を設定するために必要な設定手順は次のとおりです。

  1. 次のコマンドを使用してOSユーザーw_roseを作成します。

    # useradd w_rose
    # passwd w_rose
    Changing password for w_rose
    New password: password
    Retype new password: password
    
  2. 次のコマンドを使用してデータベース・ユーザーを作成し、OS認証接続を許可します。

    CREATE USER ops$w_rose IDENTIFIED EXTERNALLY;
    GRANT CONNECT TO ops$w_rose;
    
  3. 次のコマンドを使用してOS認証接続をテストします。

    su - w_rose
    export ORACLE_HOME=/u01/app/oracle/product/10.1.0/db_1
    export PATH=$PATH:$ORACLE_HOME/bin
    export ORACLE_SID=DEV1
    sqlplus /
    
    SQL*Plus: Release 10.1.0.3.0 - Production on Wed Jun 7 08:41:15 2006
    
    Copyright (c) 1982, 2004, Oracle.  All rights reserved.
    
    Connected to:
    Oracle Database 10g Enterprise Edition Release 10.1.0.3.0 - Production
    With the Partitioning, Oracle Label Security, OLAP and Data Mining options
    
    SQL>
    

Windowsの構成手順

Windows上でOS認証を設定するために必要な設定手順は次のとおりです。


注意:

Oracle JDBC Thinドライバは、NTSをサポートしません。

  1. 「コンピュータの管理」ダイアログ・ボックスを使用してローカル・ユーザー(たとえばw_rose)を作成します。手順は次のとおりです。

    1. 「スタート」をクリックします。

    2. 「スタート」メニューから「プログラム」「管理ツール」「コンピュータの管理」の順に選択します。

    3. プラス(「+」)記号をクリックして「ローカル ユーザーとグループ」を展開します。

    4. 「ユーザー」をクリックします。

    5. 「操作」メニューから「新しいユーザー」を選択します。

    6. ユーザーの詳細を「新しいユーザー」ダイアログ・ボックスに入力し、「作成」をクリックします。


    注意:

    前の手順で作成されるのは、ローカル・ユーザーのみです。ドメイン・ユーザーはActive Directoryで作成できます。

  2. 次のコマンドを使用してデータベース・ユーザーを作成し、OS認証接続を許可します。

    CREATE USER "OPS$yourdomain.com\p_floyd" IDENTIFIED EXTERNALLY;
    GRANT CONNECT TO "OPS$yourdomain.com\p_floyd";
    

    注意:

    Windows環境でデータベース・ユーザーを作成する場合、ユーザー名は次の形式にします。
    <OS_authentication_prefix_parameter>$<DOMAIN>\<OS_user_name>
    

    Windowsサーバーを使用する場合は、他にも検討事項があります。%ORACLE_HOME%\network\admin\sqlnet.oraファイルで次のオプションを設定する必要があります。

    SQLNET.AUTHENTICATION_SERVICES= (NTS)
    
  3. 次のコマンドを使用してOS認証接続をテストします。

    C:\> set ORACLE_SID=DB11G
    C:\> sqlplus /
    SQL*Plus: Release 11.2.0.1.0 - Production on Thu July 12 11:47:01 2007
    Copyright (c) 1982, 2008, Oracle.  All rights reserved.
    
    Connected to:
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    SQL>
    

OS認証を使用するJDBCコード

データベースに接続するためのOS認証の設定が完了したので、次のJDBCコードを使用してデータベースに接続することができます。

String url = "jdbc:oracle:thin:@oracleserver.mydomain.com:5521:dbja"
Driver driver = new oracle.jdbc.OracleDriver();
DriverManager.registerDriver(driver);
Properties props = new Properties();
Connection conn = DriverManager.getConnection( url, props);

このコードは、クライアント・マシンでp_floydによって実行されると想定しています。JDBCドライバは、JVMによって設定されるuser.nameシステム・プロパティからOSユーザー名を取得します。その結果、Thinドライバ固有の次のエラーはなくなります。

ORA-17443=Null user or password not supported in THIN driver

注意:

デフォルトで、JDBCドライバは、JVMによって設定されるuser.nameシステム・プロパティからOSユーザー名を取得します。JDBCドライバがこのシステム・プロパティを取得できない場合、またはこのシステム・プロパティの値をオーバーライドする場合は、OracleConnection.CONNECTION_PROPERTY_THIN_VSESSION_OSUSER接続プロパティを使用することができます。詳細は、次のWebサイトにあるOracle Javadocを参照してください。
http://download.oracle.com/otn/utilities_drivers/jdbc/111060/doc/javadoc/index.html

データ暗号化と整合性のサポート

サーバーの関連部分の設定によっては、Javaデータベース・アプリケーションで、Oracle Advanced Securityのデータ暗号化および整合化機能を使用できます。JDBC OCIドライバを使用している場合は、Oracleクライアントの場合と同様にパラメータを設定します。Thinドライバを使用している場合は、Javaプロパティ・オブジェクトを使用してパラメータを設定します。

暗号化は、クライアント側暗号化レベル設定と、サーバー側暗号化レベル設定の組合せに基づいて、有効または無効になります。同様に、整合性はクライアント側整合性レベル設定と、サーバー側整合性レベル設定の組合せに基づいて、有効または無効になります。

暗号化と整合性は、REJECTEDACCEPTEDREQUESTEDおよびREQUIREDの同じ設定レベルをサポートしています。表9-1は、クライアント側とサーバー側の設定の組合せごとに、この機能がオンになるかオフになるかを示しています。リモートOS認証(TCP経由)はセキュリティ上問題があるため、デフォルトで無効にされています。

表9-1 暗号化または整合性のためのクライアント/サーバー間ネゴシエーション


クライアントRejected クライアントAccepted(デフォルト) クライアントRequested クライアントRequired

サーバーRejected

OFF

OFF

OFF

接続に失敗

サーバーAccepted(デフォルト)

OFF

OFF

ON

ON

サーバーRequested

OFF

ON

ON

ON

サーバーRequired

接続に失敗

ON

ON

ON


表9-1が示すように、たとえば、クライアントが暗号化を要求し、サーバーが拒否した場合は、暗号化はオフになります。整合性の場合も同様です。逆に、サーバーが暗号化を要求し、クライアントが受け入れる場合は、暗号化はオンになります。整合性の場合も同様です。


関連項目:

『Oracle Database Advanced Security管理者ガイド』


注意:

整合性パラメータ名には、まだchecksumという用語が使用されていますが、この用語はパラメータ以外では使用されません。事実上、checksumとintegrityはシノニムです。

この項の内容は次のとおりです。

JDBC OCIドライバによるデータ暗号化と整合性のサポート

JDBC OCIドライバを使用している場合は、Oracleクライアントのインストールを伴うOracleクライアント設定が想定されるため、クライアントのSQLNET.ORAファイルの設定によって、すべてのOracleクライアントの場合と同様に、データの暗号化または整合性を使用可能または使用禁止にし、関連するパラメータを設定できます。

表9-2に、クライアント・パラメータについてまとめます。

表9-2 暗号化と整合性のためのOCIドライバ・クライアント・パラメータ

パラメータの説明 パラメータ名 可能な設定

クライアント暗号化レベル

SQLNET.ENCRYPTION_CLIENT

REJECTED ACCEPTED REQUESTED REQUIRED

クライアント暗号化選択リスト

SQLNET.ENCRYPTION_TYPES_CLIENT

RC4_40RC4_56DESDES40AES128AES192AES2563DES1123DES168

(「注意」を参照)

クライアント整合性レベル

SQLNET.CRYPTO_CHECKSUM_CLIENT

REJECTED ACCEPTED REQUESTED REQUIRED

クライアント整合性選択リスト

SQLNET.CRYPTO_CHECKSUM_TYPES_CLIENT

MD5SHA-1



注意:

Oracle Advanced Securityの国内版についてのみ、RC4_128およびRC4_256の設定も使用できます。


関連項目:

『Oracle Database Advanced Security管理者ガイド』

JDBC Thinドライバによるデータ暗号化と整合性のサポート

JDBC Thinドライバによるデータ暗号化および整合性パラメータ設定のサポートは、前の項で説明したJDBC OCIドライバ・サポートに対応しています。対応するパラメータは、データベース接続をオープンするときに使用するJavaプロパティ・オブジェクトを使用して設定できます。

表9-3は、JDBC Thinドライバのパラメータ情報です。これらのパラメータは、oracle.jdbc.OracleConnectionインタフェースで定義されています。

表9-3 暗号化と整合性のためのThinドライバ・クライアント・パラメータ

パラメータ名 パラメータ・タイプ 可能な設定

CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL

String

REJECTED ACCEPTED REQUESTED REQUIRED

CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES

String

AES256AES192AES1283DES1683DES112DES56CDES40CRC4_256RC4_128RC4_40RC4_56

CONNECTION_PROPERTY_THIN_NET_CHECKSUM_LEVEL

String

REJECTED ACCEPTED REQUESTED REQUIRED

CONNECTION_PROPERTY_THIN_NET_CHECKSUM_TYPES

String

MD5SHA1



注意:

  • ThinドライバでのOracle Advanced Securityのサポートは、JDBCクラスJARファイルに直接組み込まれているため、1つのバージョンのみが存在し、国内版と輸出版にわかれてはいません。輸出版には適するパラメータ設定のみを使用できます。

  • DES40CDES56CのCの文字は、Cipher Block Chaining(CBC)モードを示しています。


Javaでの暗号化および整合性パラメータの設定

JDBC Thinドライバがサポートするデータ暗号化および整合性パラメータを設定するには、Javaプロパティ・オブジェクト、つまりjava.util.Propertiesのインスタンスを使用します。

次の例では、Javaプロパティ・オブジェクトをインスタンス化し、それを使用して表9-3の各パラメータを設定し、その後そのプロパティ・オブジェクトを使用してデータベース接続をオープンしています。

...
Properties prop = new Properties();
prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL, "REQUIRED");
prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES, "( DES40C )");
prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_LEVEL, "REQUESTED");
prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_TYPES, "( MD5 )");

OracleDataSource ods = new OracleDataSource();
ods.setProperties(prop);
ods.setURL("jdbc:oracle:thin:@localhost:1521:main");
Connection conn = ods.getConnection();
...

暗号化タイプおよびチェックサム・タイプの値は、丸カッコで囲み、リスト形式で指定できます。複数の値を指定した場合は、サーバーとクライアントの間のネゴシエーションにより、実際に使用される値が決定されます。

例9-3は、データベースに接続して問合せを実行する前に、データ暗号化とデータ整合性のパラメータを設定する完全なクラスの例です。


注意:

この例にある文字列「REQUIRED」は、AnoServicesクラスとServiceクラスの機能によって動的に取り出されます。この方法で文字列を取り出すことも、前の例のようにソフトウェア・コードに含めることもできます。

この例を実行する前に、sqlnet.oraファイルで暗号化を有効にする必要があります。たとえば、次のコードは、暗号化についてAES256、AES192およびAES128を、チェックサムについてはMD5とSHA1をオンにする場合の例です。

  SQLNET.ENCRYPTION_SERVER = ACCEPTED 
  SQLNET.CRYPTO_CHECKSUM_SERVER = ACCEPTED 
  SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER= (MD5, SHA1) 
  SQLNET.ENCRYPTION_TYPES_SERVER= (AES256, AES192, AES128)
  SQLNET.CRYPTO_SEED = 2z0hslkdharUJCFtkwbjOLbgwsj7vkqt3bGoUylihnvkhgkdsbdskkKGhdk

例9-3 データ暗号化および整合性パラメータの設定

import java.sql.*;
import java.util.Properties;
import oracle.net.ano.AnoServices;
import oracle.jdbc.*;
 
public class DemoAESAndSHA1
{
  static final String USERNAME= "scott";
  static final String PASSWORD= "tiger";
  static final String URL = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=WXYZ)(PORT=5561))"
  +"(CONNECT_DATA=(SERVICE_NAME=mydatabaseinstance)))";
 
  public static final void main(String[] argv)
  {
    DemoAESAndSHA1 demo = new DemoAESAndSHA1();
    try
    {
      demo.run();
    }catch(SQLException ex)
    {
      ex.printStackTrace();
    }
  }
 
  void run() throws SQLException
  {
    OracleDriver dr = new OracleDriver();
    Properties prop = new Properties();
 
    // We require the connection to be encrypted with either AES256 or AES192.
    // If the database doesn't accept such a security level, then the connection attempt will fail.
    
    prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL,AnoServices.ANO_REQUIRED);
    prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES,"( " + AnoServices.ENCRYPTION_AES256
     + "," + AnoServices.ENCRYPTION_AES192 + ")");
 
    // We also require the use of the SHA1 algorithm for data integrity checking.
    
    prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_LEVEL,AnoServices.ANO_REQUIRED);
    prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_TYPES,
"( " + AnoServices.CHECKSUM_SHA1 + " )");
    prop.setProperty("user",DemoAESAndSHA1.USERNAME);
    prop.setProperty("password",DemoAESAndSHA1.PASSWORD);
    OracleConnection oraConn = (OracleConnection)dr.connect(DemoAESAndSHA1.URL,prop);
    System.out.println("Connection created! Encryption algorithm is: " + oraConn.getEncryptionAlgorithmName() + ", data 
    integrity algorithm is: " + oraConn.getDataIntegrityAlgorithmName());    
    oraConn.close();
  }
  
}

SSLのサポート

Oracle Database 11gでは、Secure Sockets Layer (SSL)プロトコルがサポートされています。SSLは広く使用されている業界標準のプロトコルで、セキュアなネットワーク通信を提供します。SSLは認証、データ暗号化およびデータ整合性を提供します。標準TCP/IPプロトコルのセキュリティ拡張で、インターネット通信に使用されます。

SSLでは、認証機能、および公開鍵/秘密鍵ペアによる暗号化の機能を提供するのに、X.509v3標準準拠のデジタル証明書が使用されます。SSLではまた、データのプライバシと整合性を保証するために、秘密鍵暗号化とデジタル署名も使用されます。SSLを介したネットワーク接続が開始されると、クライアントとサーバーでは次のようなステップを含むSSLハンドシェイクが実行されます。


注意:

Oracle Database 11gリリース1(11.1)では、ThinドライバでSSL認証がサポートされています。このため、SSL認証を使用している場合、ユーザー名とパスワードのペアを指定する必要はありません。

SSLに関する用語

SSLのコンテキストでは、次の用語がよく使用されます。

JavaバージョンのSSL

Java Secure Socket Extension(JSSE)は、SSLおよびTLSプロトコルのJavaバージョンを使用するためのフレームワークと実装を提供するものです。JSSEは、データの暗号化、サーバーとクライアントの認証、およびメッセージの整合性保持をサポートします。JSSEでは、アプリケーション開発者が直接アプリケーションに統合できる基礎要素が提供されるため、開発者は複雑なセキュリティ・アルゴリズムやハンドシェイク・メカニズムから解放され、アプリケーション開発が簡略化されます。JSSEは、Java Development Kit(JDK)1.4以上に統合され、SSLバージョン2.0と3.0をサポートします。

Oracle JDBCドライバでSSLを使用する前に、Sun社のJavaTM Secure Socket Extension(JSSE)フレームワークをよく理解しておくことをお薦めします。

JSSE標準のApplication Program Interface(API)は、javax.netjavax.net.sslおよびjavax.security.certの各パッケージで使用できます。これらのパッケージには、ソケット、サーバー・ソケット、SSLソケットおよびSSLサーバー・ソケットを作成および構成するためのクラスが用意されています。これらのパッケージには、セキュアなHTTP接続、JDK1.1ベースのプラットフォームと互換性がある公開鍵証明書API、および信頼のおける主要なマネージャ用のインタフェースも用意されています。

SSLは、Oracle Database 11gの環境においても、他のあらゆるネットワーク環境の場合と同様に機能します。この項の内容は次のとおりです。

証明書とウォレットの管理

Oracleデータベース・サーバーは、JDBCクライアント(ThinまたはOCI)とSSL接続を確立するために、ウォレットに格納されている自身の証明書を送信します。クライアントで証明書やウォレットが必要となるかどうかは、サーバーの構成によって決まります。

Oracle JDBC Thinドライバは、JSSEフレームワークを使用してSSL接続を作成します。デフォルトのプロバイダ(SunJSSE)を使用してSSLコンテキストを作成します。ただし、独自のプロバイダを指定できます。

サーバー上でSSL_CLIENT_AUTHENTICATIONパラメータが設定されていないかぎり、クライアント用の証明書は不要です。

鍵と証明書のコンテナ

Javaクライアントは、プロバイダさえあれば、Oracleウォレット、JKS、PKCS12など複数の種類のコンテナを使用することができます。Oracleウォレットの場合、SunJSSEプロバイダによって提供されるPKCS12サポートがPKCS12のすべての機能をサポートしているわけではないため、OraclePKIプロバイダを使用する必要があります。OraclePKIプロバイダを使用するには次のJARが必要です。

  • oraclepki.jar

  • osdt_cert.jar

  • osdt_core.jar

これらすべてのJARファイルは$ORACLE_HOME/jlibディレクトリにあります。

Kerberosのサポート

Oracle Database 11gリリース1 (11.1)からKerberosサポートが導入されました。Kerberosはネットワーク経由で認証ツールと強固な暗号化ツールを提供するネットワーク認証プロトコルです。Kerberosは秘密鍵暗号化を使用する方式で、全社の情報システムのセキュリティ確保を容易に実現できます。Kerberosプロトコルは強固な暗号化を使用しているため、安全でないネットワーク接続を経由しても、クライアントまたはサーバーがサーバーまたはクライアントに対して身元を証明することができます。Kerberosを使用して身元を証明したクライアントおよびサーバーは、すべての通信を暗号化して、業務においてプライバシとデータ整合性を保全することができます。

Kerberosアーキテクチャは鍵配布センター(KDC)と呼ばれる信頼できる認証サービスを軸としています。Kerberos環境のユーザーおよびサービスはプリンシパルと呼ばれ、各プリンシパルはKDCと秘密鍵(パスワードなど)を共有します。プリンシパルはscottなどのユーザーの場合も、データベース・サーバーのインスタンスの場合もあります。

Kerberosを使用するためのWindowsの構成

klist、kinitなどのツールを提供する良質なKerberosクライアントは、次のリンクの場所にあります。

http://web.mit.edu/kerberos/dist/index.html

このクライアントでは便利なGUIも提供しています。

WindowsマシンでKerberosを構成するには、次の変更を行う必要があります。

  1. デスクトップで「マイ コンピュータ」アイコンを右クリックします。

  2. 「プロパティ」を選択します。「システムのプロパティ」ダイアログ・ボックスが表示されます。

  3. 「詳細設定」タブを選択します。

  4. 「環境変数」をクリックします。「環境変数」ダイアログ・ボックスが表示されます。

  5. 「新規」をクリックして新しい利用者変数を追加します。「新しいユーザー変数」ダイアログ・ボックスが表示されます。

  6. 「変数名」フィールドに「KRB5CCNAME」と入力します。

  7. 「変数値」フィールドに「FILE:C:\Documents and Settings\<user_name>\krb5cc」と入力します。

  8. 「OK」をクリックして「新しいユーザー変数」ダイアログ・ボックスを閉じます。

  9. 「OK」をクリックして「環境変数」ダイアログ・ボックスを閉じます。

  10. 「OK」をクリックして「システムのプロパティ」ダイアログ・ボックスを閉じます。


注意:

C:\WINDOWS\krb5.iniファイルは、krb5.confファイルと内容が同じです。

Kerberosを使用するためのOracle Databaseの構成

Kerberosを使用するには、次の手順でOracle Databaseを構成します。

  1. 次のコマンドを使用してデータベースに接続します。

    SQL> connect system
    Enter password: password
    
  2. 次のコマンドを使用して、外部で身元が保証されたユーザーCLIENT@US.ORACLE.COMを作成します。

    SQL> create user "CLIENT@US.ORACLE.COM" identified externally;
    SQL> grant create session to "CLIENT@US.ORACLE.COM";
    
  3. 次のコマンドを使用して、sysdbaとしてデータベースに接続し、ディスマウントします。

    SQL> connect / as sysdba
    SQL> shutdown immediate;
    
    
  4. $T_WORK/t_init1.oraファイルに次の行を追加します。

    OS_AUTHENT_PREFIX=""
    
  5. 次のコマンドを使用してデータベースを再起動します。

    SQL> startup pfile=t_init1.ora
    
  6. sqlnet.oraファイルを編集して次の行を入れます。

    names.directory_path = (tnsnames)
    #Kerberos
    sqlnet.authentication_services = (beq,kerberos5)
    sqlnet.authentication_kerberos5_service = dbji
    sqlnet.kerberos5_conf = /home/Jdbc/Security/kerberos/krb5.conf
    sqlnet.kerberos5_keytab = /home/Jdbc/Security/kerberos/dbji.oracleserver
    sqlnet.kerberos5_conf_mit = true
    sqlnet.kerberos_cc_name = /tmp/krb5cc_5088
    # logging (optional):
    trace_level_server=16 
    trace_directory_server=/scratch/sqlnet/
    
  7. 次のコマンドを使用して、SQL*Plusを経由して接続できることを確認します。

    > kinit client
    > klist
         Ticket cache: FILE:/tmp/krb5cc_5088
         Default principal: client@US.ORACLE.COM
        
         Valid starting     Expires            Service principal
         06/22/06 07:13:29  06/22/06 17:13:29  krbtgt/US.ORACLE.COM@US.ORACLE.COM
        
        
         Kerberos 4 ticket cache: /tmp/tkt5088
         klist: You have no tickets cached
    > sqlplus '/@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracleserver.mydomain.com)(PORT=5529))
    (CONNECT_DATA=(SERVICE_NAME=mydatabaseinstance)))'
    

サンプル・コード

次の例は、Oracle Database 11gリリース2(11.2)のJDBC Thinドライバに含まれている新しいKerberos認証機能を示しています。このデモは、次の2つの使用例を説明しています。

  • 最初のシナリオでは、OSがユーザー名と資格証明をメンテナンスします。資格証明はキャッシュに格納され、ドライバは資格証明を取得してからサーバーの認証を受けようとします。この使用例はモジュールconnectWithDefaultUser()にあります。


    注意:

    1. デモのこの部分を実行する前に、次のコマンドを使用して、有効な資格証明を持っていることを確認してください。
      > /usr/kerberos/bin/kinit client
      where, the password is welcome.
      
    2. 次のコマンドを使用してチケットをリストします。

      > /usr/kerberos/bin/klist
      

  • 2番目の使用例は、アプリケーションがユーザーの資格証明を制御する事例です。これは、複数のWebユーザーが各自の資格証明を持っているアプリケーション・サーバーの場合です。この使用例はモジュールconnectWithSpecificUser()にあります。


    注意:

    このデモを実行するには、作業用の設定として、稼働中のKerberosサーバーと、Kerberos認証を使用するように構成されているOracleデータベース・サーバーが必要です。例をコンパイルして実行するには、使用されているURLを変更する必要があります。

例9-4 Kerberos認証を使用したデータベースへの接続

import com.sun.security.auth.module.Krb5LoginModule;
import java.io.IOException;
 
import java.security.PrivilegedExceptionAction;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
 
import java.util.HashMap;
import java.util.Properties;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
 
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleDriver;
import oracle.net.ano.AnoServices;
public class KerberosJdbcDemo
{
  String url ="jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)"+
    "(HOST=oracleserver.mydomain.com)(PORT=5561))(CONNECT_DATA=" +
    "(SERVICE_NAME=mydatabaseinstance)))";
 
  public static void main(String[] arv)
  {
    /* If you see the following error message [Mechanism level: Could not load
     * configuration file c:\winnt\krb5.ini (The system cannot find the path 
     * specified] it's because the JVM cannot locate your kerberos config file.
     * You have to provide the location of the file. For example, on Windows,
     * the MIT Kerberos client uses the config file: C\WINDOWS\krb5.ini:
     */
    // System.setProperty("java.security.krb5.conf","C:\\WINDOWS\\krb5.ini");
    System.setProperty("java.security.krb5.conf","/home/Jdbc/Security/kerberos/krb5.conf");
    
    KerberosJdbcDemo kerberosDemo = new KerberosJdbcDemo();
    try
    {
      System.out.println("Attempt to connect with the default user:");
      kerberosDemo.connectWithDefaultUser();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    try
    {
      System.out.println("Attempt to connect with a specific user:");
      kerberosDemo.connectWithSpecificUser();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }
  
 
  void connectWithDefaultUser() throws SQLException
  {
    OracleDriver driver = new OracleDriver();
    Properties prop = new Properties();
    
    prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_SERVICES,
      "("+AnoServices.AUTHENTICATION_KERBEROS5+")");  
    prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_KRB5_MUTUAL,
      "true");    
 
    /* If you get the following error [Unable to obtain Princpal Name for 
     * authentication] although you know that you have the right TGT in your
     * credential cache, then it's probably because the JVM can't locate your
     * cache.
     *
     * Note that the default location on windows is "C:\Documents and Settings\krb5cc_username".
     */
 
    // prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_KRB5_CC_NAME,
    /*
      On linux:
         > which kinit
         /usr/kerberos/bin/kinit
         > ls -l /etc/krb5.conf 
         lrwxrwxrwx    1 root  root   47 Jun 22 06:56 /etc/krb5.conf -> /home/Jdbc/Security/kerberos/krb5.conf
    
         > kinit client
         Password for client@US.ORACLE.COM: 
         > klist
         Ticket cache: FILE:/tmp/krb5cc_5088
         Default principal: client@US.ORACLE.COM
 
         Valid starting     Expires            Service principal
         11/02/06 09:25:11  11/02/06 19:25:11  krbtgt/US.ORACLE.COM@US.ORACLE.COM
 
 
         Kerberos 4 ticket cache: /tmp/tkt5088
         klist: You have no tickets cached
    */
    prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_KRB5_CC_NAME,
                     "/tmp/krb5cc_5088");
    Connection conn  = driver.connect(url,prop);
    String auth = ((OracleConnection)conn).getAuthenticationAdaptorName();
    System.out.println("Authentication adaptor="+auth);
    printUserName(conn);
    conn.close();
  }
 
  
  void connectWithSpecificUser() throws Exception
  {
    Subject specificSubject = new Subject();
    
    // This first part isn't really meaningful to the sake of this demo. In
    // a real world scenario, you have a valid "specificSubject" Subject that
    // represents a web user that has valid Kerberos credentials.
    Krb5LoginModule krb5Module = new Krb5LoginModule();
    HashMap sharedState = new HashMap();
    HashMap options = new HashMap();
    options.put("doNotPrompt","false");
    options.put("useTicketCache","false");
    options.put("principal","client@US.ORACLE.COM");
    
    krb5Module.initialize(specificSubject,newKrbCallbackHandler(),sharedState,options);
    boolean retLogin = krb5Module.login();
    krb5Module.commit();
    if(!retLogin)
      throw new Exception("Kerberos5 adaptor couldn't retrieve credentials (TGT) from the cache"); 
      
    // to use the TGT from the cache:   
    // options.put("useTicketCache","true");
    // options.put("doNotPrompt","true");
    // options.put("ticketCache","C:\\Documents and Settings\\user\\krb5cc");
    // krb5Module.initialize(specificSubject,null,sharedState,options);
 
 
    // Now we have a valid Subject with Kerberos credentials. The second scenario
    // really starts here:
    // execute driver.connect(...) on behalf of the Subject 'specificSubject':
    Connection conn = 
      (Connection)Subject.doAs(specificSubject, new PrivilegedExceptionAction()
        {
          public Object run()
          {
            Connection con = null;
            Properties prop = new Properties();
            prop.setProperty(AnoServices.AUTHENTICATION_PROPERTY_SERVICES, 
                             "(" + AnoServices.AUTHENTICATION_KERBEROS5 + ")");
            try
            {
              OracleDriver driver = new OracleDriver();
              con = driver.connect(url, prop);
 
            } catch (Exception except)
            {
              except.printStackTrace();
            }
            return con;
          }
        });
 
    String auth = ((OracleConnection)conn).getAuthenticationAdaptorName();
    System.out.println("Authentication adaptor="+auth);
    printUserName(conn);
    conn.close();
  }
  
  void printUserName(Connection conn) throws SQLException
  {
    Statement stmt = null;
    try
    {
      stmt = conn.createStatement();
      ResultSet rs = stmt.executeQuery("select user from dual");
      while(rs.next())
        System.out.println("User is:"+rs.getString(1));
      rs.close();
    }
    finally
    {
      if(stmt != null)
        stmt.close();
    }
  }
}
 
class KrbCallbackHandler implements CallbackHandler
{
 public void handle(Callback[] callbacks) throws IOException, 
                                                 UnsupportedCallbackException
 {
   for (int i = 0; i < callbacks.length; i++)
   {
     if (callbacks[i] instanceof PasswordCallback)
     {
       PasswordCallback pc = (PasswordCallback)callbacks[i];
       System.out.println("set password to 'welcome'");
       pc.setPassword((new String("welcome")).toCharArray());
     } else
     {
       throw new UnsupportedCallbackException(callbacks[i], 
                                              "Unrecognized Callback");
     }
   }
 }
}

RADIUSのサポート

Oracle Database 11gリリース1(11.1)から、リモート認証ダイアルイン・ユーザー・サービス(RADIUS)が導入されました。RADIUSは、最も広く知られている、リモートでの認証とアクセスを可能にするクライアント/サーバー・セキュリティ・プロトコルです。Oracle Advanced Securityは、この標準をクライアント/サーバー・ネットワーク環境で使用して、RADIUSプロトコルをサポートするあらゆる認証方式の使用を可能にします。RADIUSは、トークン・カードやスマート・カードなど、いろいろな認証メカニズムで使用できます。この項の内容は次のとおりです。

RADIUSを使用するためのOracle Databaseの構成

RADIUSを使用するには、次の手順でOracle Databaseを構成します。

  1. 次のコマンドを使用してデータベースに接続します。

    SQL> connect system
    Enter password: password
    
  2. 次のコマンドを使用して、データベース内から新規ユーザーasoを作成します。

    SQL> create user aso identified externally;
    SQL> grant create session to aso;
    
  3. 次のコマンドを使用して、sysdbaとしてデータベースに接続し、ディスマウントします。

    SQL> connect / as sysdba
    SQL> shutdown immediate;
    
  4. t_init1.oraファイルに次の行を追加します。

    os_authent_prefix = ""
    

    注意:

    テストが終了したら、t_init1.oraファイルに加えられたこれまでの変更を元に戻す必要があります。

  5. 次のコマンドを使用してデータベースを再起動します。

    SQL> startup pfile=?/work/t_init1.ora
    
  6. 次の行のみが含まれるようにsqlnet.oraファイルを変更します。

    sqlnet.authentication_services = ( beq, radius)
    sqlnet.radius_authentication = <RADUIUS_SERVER_HOST_NAME>
    sqlnet.radius_authentication_port = 1812
    sqlnet.radius_authentication_timeout = 120
    sqlnet.radius_secret=/home/Jdbc/Security/radius/radius_key
    # logging (optional):
    trace_level_server=16
    trace_directory_server=/scratch/sqlnet/
    
  7. 次のコマンドを使用して、SQL*Plusを経由して接続できることを確認します。

    >sqlplus 'aso/1234@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=oracleserver.mydomain.com)(PORT=5529))
    (CONNECT_DATA=(SERVICE_NAME=mydatabaseinstance)))'
    

サンプル・コード

この例は、Oracle Database 11gリリース2(11.2)のJDBC Thinドライバに含まれている新しいRADIUS認証機能を示しています。作業用の設定として、稼働中のKerberosサーバーと、Kerberos認証を使用するように構成されているOracleデータベース・サーバーが必要です。例をコンパイルして実行するには、指定されているURLを変更する必要があります。

例9-5 RADIUS認証を使用したデータベースへの接続

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleDriver;
import oracle.net.ano.AnoServices;
public class RadiusJdbcDemo
{  
  String url ="jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)"+
    "(HOST=oracleserver.mydomain.com)(PORT=5561))(CONNECT_DATA=" +
    "(SERVICE_NAME=mydatabaseinstance)))";
 
  public static void main(String[] arv)
  {
    RadiusJdbcDemo radiusDemo = new RadiusJdbcDemo();
    try
    {
      radiusDemo.connect();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }
  
  /*
   * This method attempts to logon to the database using the RADIUS
   * authentication protocol.
   * 
   * It should print the following output to stdout:
   * -----------------------------------------------------
   * Authentication adaptor=RADIUS
   * User is:ASO
   * -----------------------------------------------------
   */
  void connect() throws SQLException
  {
    OracleDriver driver = new OracleDriver();
    Properties prop = new Properties();
    
    prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_AUTHENTICATION_SERVICES,
      "("+AnoServices.AUTHENTICATION_RADIUS+")");
    // The user "aso" needs to be properly setup on the radius server with
    // password "1234".
    prop.setProperty("user","aso");
    prop.setProperty("password","1234");
    
    Connection conn  = driver.connect(url,prop);
    String auth = ((OracleConnection)conn).getAuthenticationAdaptorName();
    System.out.println("Authentication adaptor="+auth);
    printUserName(conn);
    conn.close();
  }
 
  
  void printUserName(Connection conn) throws SQLException
  {
    Statement stmt = null;
    try
    {
      stmt = conn.createStatement();
      ResultSet rs = stmt.executeQuery("select user from dual");
      while(rs.next())
        System.out.println("User is:"+rs.getString(1));
      rs.close();
    }
    finally
    {
      if(stmt != null)
        stmt.close();
    }
  }
}

セキュアな外部パスワード記憶域

アプリケーションがパスワード資格証明を使用してデータベースに接続する大規模なデプロイメントでの代替として、クライアント側のOracle Walletにそれらの資格証明を格納できます。Oracle Walletは、資格証明の認証および署名の格納に使用されるセキュアなソフトウェア・コンテナです。

クライアント側のOracleウォレットにデータベースのパスワード資格証明を格納すると、アプリケーション・コードやバッチ・ジョブ、スクリプトにユーザー名とパスワードを埋め込む必要がなくなります。このため、スクリプトやアプリケーション・コード内にパスワードが露出する危険性が減少し、ユーザー名やパスワードを変更するたびにコードを変更する必要がなくなるため、管理が単純化されます。また、アプリケーション・コードを変更する必要がないため、これらのユーザー・アカウントに対してパスワード管理ポリシーをさらに簡単に強制適用できるようになります。

oracle.net.wallet_location接続プロパティを設定して、ウォレットの場所を指定できます。JDBCドライバは、このウォレットからユーザー名とパスワードのペアを取得できます。


関連項目:

セキュアな外部パスワード記憶域を使用するようにクライアントを構成する方法、およびその記憶域で資格証明を管理する方法については、『Oracle Database Advanced Security管理者ガイド』を参照してください。