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は、業界標準に基づくデータ暗号化、データ整合性、サード・パーティ認証、シングル・サインオンおよびアクセス認可の機能を提供します。Oracle Database 11gリリース1以降、JDBC OCIとJDBC Thinドライバの両方がすべてのOracle Advanced Security機能をサポートしています。
ノート:
JDBC ojdbc.policy
のセキュリティ・ポリシー・ファイルを使用する場合、次のリンクからファイルをダウンロードできます。
http://www.oracle.com/technetwork/index.html
ojdbc.policy
ファイルには、Javaセキュリティ・マネージャの制御環境でアプリケーションを実行する必要がある付与された権限が含まれます。このファイル自体をJavaポリシー・ファイルとして使用するか、このファイルからコンテンツを取得してJavaポリシー・ファイルのコンテンツを追加できます。このファイルには、次のような権限が含まれます。
-
権限
java.util.PropertyPermission "user.name", "read";
などの常に必要ないくつかの必須権限 -
いくつかのドライバ固有の権限(たとえば、JDBC OCIドライバでは権限
java.lang.RuntimePermission "loadLibrary.ocijdbc12";
が必要です) -
XA、XDB、FCFなどに関連する権限などのいくつかの機能ベースの権限
要件に応じてファイルに記述されているシステム・プロパティまたは権限のダイレクト値を設定できます。
この章の構成は、次のとおりです。
9.1 Oracle Advanced Securityのサポート
この項では、次の概念について説明します。
9.1.1 Oracle Advanced Securityの概要
Oracle Advanced Securityでは、次のセキュリティ機能をサポートしています。
-
データの暗号化
エンタープライズ・ネットワークおよびインターネット上でやりとりされる機密情報は、復号化キーによってのみ解読できる形式に情報を変換する暗号化アルゴリズムにより保護できます。サポートされている暗号化アルゴリズムには、RC4、DES、3DES、AESなどがあります。
送信中のデータの整合性を保証するために、Oracle Advanced Securityでは暗号化によってセキュアなメッセージ・ダイジェストを生成します。Oracle Database 12cリリース1 (12.1)以降、ハッシュ・アルゴリズムのSHA-2リストもサポートされているので、Oracle Advanced Securityでは次のハッシュ・アルゴリズムを使用して、セキュアなメッセージ・ダイジェストを生成し、ネットワーク上で送信される各メッセージにこれを含めます。
これにより、やりとりされるデータは、データの変更、パケットの削除、反射攻撃などの攻撃から保護されます。
次のコードの抜粋に、前述のアルゴリズムのいずれかを使用したチェックサムの計算方法を示します。
prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_TYPES, "( SHA1)"); prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_LEVEL, "REQUIRED");
-
厳密認証
分散環境でネットワーク・セキュリティを確保するには、ユーザーを認証し、資格証明を確認する必要があります。パスワード認証は、認証で最も一般的な手段です。Oracle Databaseでは、Oracle認証アダプタを使用して厳密な認証を行います。Oracle認証アダプタは、デジタル証明書を使用したSSLを含む様々なサード・パーティ認証サービスをサポートします。Oracle Databaseは、業界で標準的な次の認証方式をサポートしています。
-
Kerberos
-
Remote Authentication Dial-In User Service(RADIUS)
-
Secure Sockets Layer(SSL)
-
9.1.2 JDBC OCIドライバによるOracle Advanced Securityのサポート
JDBC OCIドライバを使用している場合は、Oracleクライアントがインストールされているコンピュータから実行していることが想定されるため、Oracle Advanced Securityと組込みサード・パーティ機能のサポートは、Oracleクライアントによって提供されるサポートとほとんど同じです。Advanced Security機能が使用されているかどうかは、クライアント・コンピュータのsqlnet.ora
ファイル内の、関連する設定の内容によって判断できます。
ノート:
Oracle Database 12cリリース1 (12.1)以降、sqlnet.ora
ファイルにあるOCI固有の構成パラメータのかわりに、新しいXML構成ファイルoraaccess.xml
にある構成パラメータを使用することをお薦めします。ただし、sqlnet.ora
ファイル内の構成パラメータもまだサポートされています。
Oracle Database 11gリリース1以降では、パスワードを入力しないでデータベースに接続しようとすると、JDBC OCIドライバは外部認証を使用しようとします。JDBC OCIドライバを使用して、パスワードを入力しないでデータベースに接続する例を次に示します。
SSL認証
次のコードでは、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=localhost)(PORT=5221))" +"(CONNECT_DATA=(SERVICE_NAME=orcl)))"; Driver driver = new oracle.jdbc.OracleDriver(); Properties props = new Properties(); Connection conn = driver.connect( url, props ); conn.close(); } }
データソースの使用
次のコードでは、データソースを使用してデータベースに接続する方法を示します。
例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=localhost)(PORT=5221))" +"(CONNECT_DATA=(SERVICE_NAME=orcl)))"; OracleConnectionPoolDataSource ocpds = new OracleConnectionPoolDataSource(); ocpds.setURL(url); PooledConnection pc = ocpds.getPooledConnection(); Connection conn = pc.getConnection(); } }
ノート:
Javaに関する前述の重要な例外は、アプリケーションでネイティブ・スレッドを使用している場合にのみ、Secure Sockets Layer (SSL)プロトコルがOracle JDBC OCIドライバでサポートされているという点です。通常、グリーン・スレッドがデフォルトで設定されているため、特に注意が必要です。
9.1.3 JDBC ThinドライバによるOracle Advanced Securityのサポート
JDBC Thinドライバでは、Oracleクライアントがインストールされていること、またはsqlnet.ora
ファイルが存在していることを前もって想定できません。したがって、Javaアプローチを使用してOracle Advanced Securityをサポートします。Oracle Advanced Securityを実装するJavaクラスは、ojdbc6.jar
ファイルおよびojdbc7.jar
ファイルに含まれています。暗号化と整合性のためのセキュリティ・パラメータは、通常のようにsqlnet.ora
ファイル内に設定されるのではなく、JavaのProperties
オブジェクトか、またはシステム・プロパティを使用して設定されます。
9.2 ログイン認証のサポート
JDBCを介した基本ログイン認証では、Oracleサーバーへの他のログイン方法と同様に、ユーザー名とパスワードが要求されます。Javaプロパティ・オブジェクトを使用するか、またはgetConnection
メソッドを直接コールして、ユーザー名とパスワードを指定します。これは、使用しているクライアント側Oracle JDBCドライバにかかわらず適用されますが、サーバー側内部ドライバを使用している場合には、特殊な直接接続を使用しており、ユーザー名またはパスワードを要求しないため、関係ありません。
Oracle Database 12cリリース1 (12.1.0.2)以降、Oracle JDBC Thinドライバは、PBKDF2-SHA2
アルゴリズムをサポートしているJDK 8などのJDKを使用してアプリケーションを実行する場合、O7L_MR
クライアント機能をサポートしています。JDK 7を使用してアプリケーションを実行する場合は、PBKDF2-SHA2
アルゴリズムをサポートしているサードパーティ製セキュリティ・プロバイダを追加する必要があります。そうしないと、O7L_MR
クライアント機能を必要とする新規の12a
パスワード検証機能が、ドライバでサポートされません。
SQLNET.ALLOWED_LOGON_VERSION_SERVER
パラメータを12a
に設定してOracle Database 12cリリース1 (12.1.0.2)を使用している場合は、次の点に注意してください。
-
12.1.0.2 Oracle JDBC Thinドライバと、JDK 8、または
PBKDF2-SHA2
アルゴリズムをサポートしているサードパーティ製セキュリティ・プロバイダを追加したJDK 7も、使用する必要があります -
旧バージョンのOracle JDBC Thinドライバを使用すると、次のエラーが発生します。
ORA-28040: No matching authentication protocol
-
12.1.0.2 Oracle JDBC ThinドライバをJDK 7とともに使用する場合も、
PBKDF2-SHA2
アルゴリズムをサポートしているサードパーティ製セキュリティ・プロバイダを追加していないと、同じエラーが発生します。
9.3 厳密認証のサポート
Oracle Advanced Securityでは、Oracle Databaseユーザーに対する外部認証が可能です。外部認証には、RADIUS、Kerberos、証明書ベースの認証、トークン・カードおよびスマート・カードなどが使用されます。この認証方法は、厳密認証と呼ばれます。Oracle JDBCドライバでサポートしている厳密認証方法は次のとおりです。
-
Kerberos
-
RADIUS
-
SSL (証明書ベースの認証)
9.4 データ暗号化と整合性のサポート
この項では、次の概念について説明します。
9.4.1 JDBCによるデータ暗号化と整合性のサポートの概要
サーバーの関連部分の設定によっては、Javaデータベース・アプリケーションで、Oracle DatabaseとOracle Advanced Securityのデータ暗号化および整合化機能を使用できます。JDBC OCIドライバを使用している場合は、Oracleクライアントの場合と同様にパラメータを設定します。Thinドライバを使用している場合は、Javaプロパティ・オブジェクトを使用してパラメータを設定します。
暗号化は、クライアント側暗号化レベル設定と、サーバー側暗号化レベル設定の組合せに基づいて、有効または無効になります。同様に、整合性はクライアント側整合性レベル設定と、サーバー側整合性レベル設定の組合せに基づいて、有効または無効になります。
暗号化と整合性は、REJECTED
、ACCEPTED
、REQUESTED
および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が示すように、たとえば、クライアントが暗号化を要求し、サーバーが拒否した場合は、暗号化はオフになります。整合性の場合も同様です。逆に、サーバーが暗号化を要求し、クライアントが受け入れる場合は、暗号化はオンになります。整合性の場合も同様です。
関連項目:
-
透過的データ暗号化(TDE)の詳細は、Oracle Database Advanced Securityガイドを参照してください。
-
TDE以外のデータ暗号化および整合性機能の詳細は、『Oracle Databaseセキュリティ・ガイド』を参照してください。
ノート:
整合性パラメータ名には、まだchecksumという用語が使用されていますが、この用語はパラメータ以外では使用されません。事実上、checksumとintegrityはシノニムです。
9.4.2 JDBC OCIドライバによるデータ暗号化と整合性のサポート
JDBC OCIドライバを使用している場合は、Oracleクライアントのインストールを伴うOracleクライアント設定が想定されるため、クライアントのsqlnet.ora
ファイルの設定によって、すべてのOracleクライアントの場合と同様に、データの暗号化または整合性を使用可能または使用禁止にし、関連するパラメータを設定できます。
ノート:
Oracle Database 12cリリース1 (12.1)以降、sqlnet.ora
ファイルにあるOCI固有の構成パラメータのかわりに、新しいXML構成ファイルoraaccess.xml
にある構成パラメータを使用することをお薦めします。ただし、sqlnet.ora
ファイル内の構成パラメータもまだサポートされています。
表9-2に、クライアント・パラメータについてまとめます。
表9-2 暗号化と整合性のためのOCIドライバ・クライアント・パラメータ
パラメータの説明 | パラメータ名 | 可能な設定 |
---|---|---|
クライアント暗号化レベル |
|
|
クライアント暗号化選択リスト |
|
(「ノート」を参照) |
クライアント整合性レベル |
|
|
クライアント整合性選択リスト |
|
|
ノート:
Oracle Advanced Securityの国内版についてのみ、RC4_128
およびRC4_256
の設定も使用できます。
9.4.3 JDBC Thinドライバによるデータ暗号化と整合性のサポート
JDBC Thinドライバによるデータ暗号化および整合性パラメータ設定のサポートは、前の項で説明したJDBC OCIドライバ・サポートに対応しています。Javaプロパティ・オブジェクトを介して対応するパラメータを設定し、データベース接続のオープン中にこれを使用できます。
データ暗号化と整合性レベルのデフォルト値は、サーバー側もクライアント側もACCEPTED
です。これにより、サーバー側とクライアント側のいずれかの接続を構成して、接続ペアに必要なセキュリティ・レベルを獲得できます。これにより、Oracleサーバーに接続する複数のOracleクライアントがある場合、すべての接続の暗号化と整合性を有効にするために、サーバー側のsqlnet.ora
ファイルで暗号化と整合性レベルをREQUESTED
に変更するだけでよいので、プログラムの効率性が向上します。クライアンの設定を個別に変更する必要がないので、時間と労力を節約できます。
表9-3は、JDBC Thinドライバのパラメータ情報です。これらのパラメータは、oracle.jdbc.OracleConnection
インタフェースで定義されています。
表9-3 暗号化と整合性のためのThinドライバ・クライアント・パラメータ
パラメータ名 | パラメータ・タイプ | 可能な設定 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
ノート:
-
Oracle Advanced SecurityのThinドライバのサポートは、JDBCクラスのJARファイルに直接組み込まれています。そのため、国内版と輸出版で別々のバージョンはありません。輸出版には適するパラメータ設定のみを使用できます。
9.4.4 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, "( AES256 )"); prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_LEVEL, "REQUESTED"); prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_CHECKSUM_TYPES, "( SHA1 )"); OracleDataSource ods = new OracleDataSource(); ods.setProperties(prop); ods.setURL("jdbc:oracle:thin:@localhost:5221:main"); Connection conn = ods.getConnection(); ...
暗号化タイプおよびチェックサム・タイプの値は、丸カッコで囲み、リスト形式で指定できます。複数の値を指定した場合は、サーバーとクライアントの間のネゴシエーションにより、実際に使用される値が決定されます。
例
例9-3は、データベースに接続して問合せを実行する前に、データ暗号化とデータ整合性のパラメータを設定する完全なクラスの例です。
ノート:
この例にある文字列REQUIRED
は、AnoServices
クラスとService
クラスの機能によって動的に取り出されます。この方法で文字列を取り出すことも、前の例のようにソフトウェア・コードに含めることもできます。
この例を実行する前に、sqlnet.ora
ファイルで暗号化を有効にする必要があります。たとえば、次のコードは、暗号化についてAES256、AES192およびAES128を、チェックサムについてはSHA1をオンにする場合の例です。
SQLNET.ENCRYPTION_SERVER = ACCEPTED SQLNET.CRYPTO_CHECKSUM_SERVER = ACCEPTED SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER = (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= "HR"; static final String PASSWORD= "hr"; static final String URL = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=5221))" +"(CONNECT_DATA=(SERVICE_NAME=orcl)))"; 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(); } }
9.5 SSLのサポート
この節では、以下のトピックについて説明します。
9.5.1 JDBCによるSSLのサポートの概要
Oracle Database 19cでは、Secure Sockets Layer (SSL)プロトコルがサポートされています。SSLは広く使用されている業界標準のプロトコルで、セキュアなネットワーク通信を提供します。SSLは認証、データ暗号化およびデータ整合性を提供します。標準TCP/IPプロトコルのセキュリティ拡張で、インターネット通信に使用されます。
SSLでは、認証機能、および公開および秘密キー・ペアによる暗号化の機能を提供するのに、X.509v3標準準拠のデジタル証明書が使用されます。SSLではまた、データのプライバシと整合性を保証するために、秘密キー暗号化とデジタル署名も使用されます。SSLを介したネットワーク接続が開始されると、クライアントとサーバーでは次のようなステップを含むSSLハンドシェイクが実行されます。
-
クライアントとサーバーとの間で、使用する暗号スイートを決めるためのネゴシエーションが行われます。これには、データ転送に使用する暗号化アルゴリズムの決定も含まれます。
-
サーバーが自分の証明書をクライアントに送信し、クライアントは、その証明書が信頼できる認証機関(CA)によって署名されているかどうかを検証します。このステップにより、サーバーの身元が検証されます。
-
クライアント認証が必要な場合は、クライアントが自分自身の証明書をサーバーに送信し、サーバーは、その証明書が信頼できるCAによって署名されているかどうかを検証します。
-
クライアントとサーバーが、公開キー暗号化を使用してキー情報を交換します。この情報に基づき、双方でセッション・キーが生成されます。クライアントとサーバーとの間の以降のやりとりはすべて、このセッション・キーのセットと、ネゴシエーションにより決定した暗号スイートを使用して、暗号化/復号化されます。
ノート:
Oracle Database 11gリリース1 (11.1)では、ThinドライバでSSL認証がサポートされています。このため、SSL認証を使用している場合、ユーザー名とパスワードのペアを指定する必要はありません。SSLに関する用語
SSLのコンテキストでは、次の用語がよく使用されます。
-
証明書: 証明書とは、公開キーとエンティティをバインドする、デジタル署名付きドキュメントのことです。証明書は、公開キーが適切なエンティティに属していることを検証するために使用します。
-
認証機関: 認証機関(CA)は、デジタル署名付き証明書(他のエンティティによって使用される)を発行するエンティティです。認証局とも呼ばれます。
-
暗号スイート: 暗号スイートとは、SSL対応のネットワーク上で送信されるデータを暗号化するために使用される、暗号化アルゴリズムとキー・サイズのセットのことです。
-
秘密キー: 秘密キーは、ネットワークを介して伝送されることのない、文字どおり秘密のキーです。秘密キーは、対応する公開キーを使用して暗号化されたメッセージを復号化するために使用されます。また、証明書に署名する際にも使用されます。その証明書を検証する際には、対応する公開キーが使用されます。
-
公開キー: 公開キーとは、公開したり、電子メール・メッセージのような通常の手段で送信したりできる暗号化キーのことです。公開キーは、SSL経由で送信されるメッセージを暗号化するために使用されます。また、対応する秘密キーによって署名された証明書を検証する際にも使用されます。
-
キー・ストアまたはウォレット: ウォレットとは、資格証明の認証や署名を格納するために使用される、パスワード保護付きのコンテナのことです。ウォレット内には、SSLで必要となる、秘密キー、証明書、および信頼できる証明書が格納されます。
-
セキュリティ・プロバイダ: セキュリティに関連したいくつかの機能を提供するJava実装。プロバイダは、キーストア・ファイルのデコードを行います。
-
キーストア・サービス(KSS): Oracle Platform Securityサービスのコンポーネント。KSSを使用すると、キーストアは
kss://
スキームを使用したURIとして(ファイル名ではなく)参照されます。
JavaバージョンのSSL
Java Secure Socket Extension(JSSE)は、SSLおよびTLSプロトコルのJavaバージョンを使用するためのフレームワークと実装を提供するものです。JSSEは、データの暗号化、サーバーとクライアントの認証、およびメッセージの整合性保持をサポートします。アプリケーション開発者が直接アプリケーションに統合できる基礎要素が提供されるため、開発者は複雑なセキュリティ・アルゴリズムやハンドシェイク・メカニズムから解放され、アプリケーション開発が簡略化されます。JSSEは、Java Development Kit(JDK)1.4以上に統合され、SSLバージョン2.0と3.0をサポートします。
Oracle JDBCドライバでSSLを使用する前に、JavaTM Secure Socket Extension(JSSE)フレームワークをよく理解しておくことをお薦めします。
JSSE標準のApplication Program Interface(API)は、javax.net
、javax.net.ssl
およびjavax.security.cert
の各パッケージで使用できます。これらのパッケージには、ソケット、サーバー・ソケット、SSLソケットおよびSSLサーバー・ソケットを作成および構成するためのクラスが用意されています。これらのパッケージには、セキュアなHTTP接続、JDK1.1ベースのプラットフォームと互換性がある公開キー証明書API、および信頼のおける主要なマネージャ用のインタフェースも用意されています。
SSLは、Oracle Database 18cの環境においても、他のあらゆるネットワーク環境の場合と同様に機能します。
ノート:
プログラムでJSSEを使用するには、JavaTM Secure Socket Extension (JSSE)フレームワークをよく理解している必要があります。9.5.2 証明書とウォレットの管理について
Oracle Databaseサーバーは、JDBCクライアント(ThinまたはOCI)とSSL接続を確立するために、ウォレットに格納されている自身の証明書を送信します。クライアントで証明書やウォレットが必要となるかどうかは、サーバーの構成によって決まります。
Oracle JDBC Thinドライバは、JSSEフレームワークを使用してSSL接続を作成します。デフォルトのプロバイダ(SunJSSE)を使用してSSLコンテキストを作成します。ただし、独自のプロバイダを指定できます。
サーバー上でSSL_CLIENT_AUTHENTICATION
パラメータが設定されていないかぎり、クライアント用の証明書は不要です。
9.5.3 キーと証明書のコンテナについて
Javaクライアントは、プロバイダさえあれば、Oracleウォレット、JKS、PKCS12など複数の種類のコンテナを使用することができます。Oracleウォレットの場合、SunJSSEプロバイダによって提供されるPKCS12サポートがPKCS12のすべての機能をサポートしているわけではないため、OraclePKIプロバイダを使用する必要があります。OraclePKIプロバイダを使用するには次のJARが必要です。
-
oraclepki.jar
-
osdt_cert.jar
-
osdt_core.jar
これらすべてのJARファイルは$ORACLE_HOME/jlib
ディレクトリにあります。
9.5.4 JDBC ThinおよびJKSを使用したTLSバージョン1.2でのデータベース接続
TLSバージョン1.2を使用してデータベースに接続するようにOracle JDBC Thinドライバを構成するには、次のステップを実行します。
-
必ずJDKの最新の更新を使用します
更新されたバージョンにはSSLバージョン1.2の使用に必要なバグ修正が含まれているため、JDK 7またはJDK 8のいずれかの最新の更新を使用します。
-
JCEファイルをインストールします
JDKにJava Cryptography Extension (JCE)無制限強度の管轄ポリシー・ファイルをインストールします。使用しているJDKバージョンに関係なく、これらのファイルがなくては強力な暗号スイート(
TLS_RSA_WITH_AES_256_CBC_SHA256
など)が有効にならないためです。これらのファイルは次のページでダウンロードできます。http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
また、JDK 7を使用している場合、強力な暗号スイートを明示的に有効にする必要があります。たとえば、JDK 7で
TLS_RSA_WITH_AES_256_CBC_SHA256
などの強力な暗号スイートを使用している場合、oracle.net.ssl_cipher_suites
接続プロパティでこれを有効にする必要があります。 -
JKSファイルまたはウォレットを使用します
ノート:
Oracle Databaseリリース18c以降、
ojdbc.properties
という新しい構成ファイルでTLSの構成プロパティを指定できます。このファイルを使用すると、クラウドでのデータベース・サービスへの接続が容易になります。
前述のステップをすべて実行した後に問題が発生した場合、トレースをオンにして-Djavax.net.debug=all
オプションを使用して問題を診断します。
9.5.5 SSL接続の自動構成
Oracle Databaseリリース18c以降、デフォルト値を使用するか、セキュリティ・プロバイダを手動で追加または更新することなく接続構成値を解決するためのプログラム・ロジックを使用することができます。次の2つの方法で構成値を解決できます。
9.5.5.1 プロバイダの解決
特定のキーストア・タイプの場合、JDBCドライバはキーストアをロードするために使用されるプロバイダ実装を解決できます。これらのタイプの場合、Javaセキュリティを使用してプロバイダを登録する必要はありません。プロバイダ実装がCLASSPATH
にあるかぎり、ドライバはセキュリティ・プロバイダをインスタンス化できます。
次のキーストア・タイプは、既知のプロバイダにマップされます。
-
SSO:
oracle.security.pki.OraclePKIProvider
-
KSS:
oracle.security.jps.internal.keystore.provider.FarmKeyStoreProvider
ドライバは、指定されたタイプにプロバイダが登録されていない場合にのみ、プロバイダを解決しようとします。
oraclepki.jar
ファイルがCLASSPATHにある場合、ドライバはOracle PKIプロバイダを次の方法で自動的にロードできます。
java –cp oraclepki.jar:ojdbc8.jar –D javax.net.ssl.keyStore=/path/to/wallet/cwallet.sso MyApp
同様に、oracle.net.wallet_location
接続プロパティの指定値の場合、ドライバはOracle PKIプロバイダを次の方法で自動的にロードできます。
java –cp .:oraclepki.jar:ojdbc8.jar –D oracle.net.wallet_location=file:/path/to/wallet/cwallet.sso MyApp
ノート:
orapkiツール(ewallet.p12
ファイル)によって作成されたPKCS12タイプの場合、orapkiツールによって作成されたPKCS12ファイルにはASN1 Key Bag要素(タイプ・コード: 1.2.840.113549.1.12.10.1.1)が含まれているため、Javaセキュリティを使用してOraclePKIProvider
を登録する必要があります。Sun PKCS12実装はKey Bagタイプをサポートしていないため、ewallet.p12
ファイルの読取りを試みると、エラーがスローされます。HotSpotおよびOpen JDKユーザーの場合、Sunプロバイダは、PKCS12プロバイダとしてバンドルされます。つまり、PKCS12プロバイダにはすでに登録済のプロバイダがあり、ドライバはこれをオーバーライドしようとしません。
9.5.5.2 キーストア・タイプ(KSS)の自動解決
JDBCドライバでは、javax.net.ssl.keyStore
およびjavax.net.ssl.trustStore
プロパティの値に基づいて共通のキーストア・タイプを解決できるため、これらのプロパティを使用してタイプを指定する必要がなくなります。
認識済のファイル拡張子を持つキーストアまたはトラスト・ストア
認識済のファイル拡張子を持つキーストアまたはトラスト・ストアは、次のタイプにマップされます。
-
ファイル拡張子
.jks
は、JKSとしてjavax.net.ssl.keyStoreType
に解決されます。java –cp ojdbc8.jar –D javax.net.ssl.keyStore=/path/to/keystore/keystore.jks MyApp
-
ファイル拡張子
.sso
は、SSOとしてjavax.net.ssl.keyStoreType
に解決されます。java –cp ojdbc8.jar –D javax.net.ssl.keyStore=/path/to/keystore/keystore.sso MyApp
-
ファイル拡張子
.p12
は、PKCS12としてjavax.net.ssl.keyStoreType
に解決されます。java –cp ojdbc8.jar –D javax.net.ssl.keyStore=/path/to/keystore/keystore.p12 MyApp
-
ファイル拡張子
.pfx
は、PKCS12としてjavax.net.ssl.keyStoreType
に解決されます。java –cp ojdbc8.jar –D javax.net.ssl.keyStore=/path/to/keystore/keystore.pfx MyApp
URIを使用したキーストアまたはトラスト・ストア
キーストアまたはトラスト・ストアがkss://
スキームを使用したURIである場合、KSSタイプにマップされます。
java –cp ojdbc8.jar –D javax.net.ssl.keyStore=kss://MyStripe/MyKeyStore MyApp
ノート:
デフォルト・タイプの解決をオーバーライドするために、javax.net.ssl.trustStoreType
およびjavax.net.ssl.keyStoreType
プロパティを設定できます。
9.5.6 デフォルトのSSLコンテキストのサポート
TLS構成に対してよりきめ細やかな制御を必要とするアプリケーションの場合は、SSLContext.getDefault
メソッドによって返されるSSLContext
を使用するように、JDBCドライバを構成できます。ドライバでデフォルトのSSLContext
を使用するには、次のいずれかの方法を使用します。
-
javax.net.ssl.keyStore=NONE
-
javax.net.ssl.trustStore=NONE
デフォルトのSSLContext
を使用して、ファイルベースではないキーストア・タイプをサポートできます。このようなキーストア・タイプの一般的な例には、ハードウェアベースのスマート・カードが含まれます。load(KeyStore.LoadStoreParameter)
メソッドへのプログラム的なコールを必要とするキーストア・タイプもこのカテゴリに属します。
9.5.7 キーストア・サービスのサポート
このリリースのOracle Databaseでは、JDBCドライバでのキーストア・サービス(KSS)のサポートが導入されています。つまり、WebLogic Serverでキーストア・サービスを構成した場合、JDBCアプリケーションを既存のキーストア・サービス構成と統合できるようになりました。
ドライバは、キーストア・サービスによって管理されるキーストアをロードできます。javax.net.ssl.keyStore
プロパティまたはjavax.net.ssl.trustStore
プロパティの値がkss://
のスキームのURIである場合、ドライバはキーストア・サービスからキーストアをロードします。
権限ベースの保護の場合、次のパーミッションをojdbc JARファイルに付与する必要があります。
permission KeyStoreAccessPermission "stripeName=*,keystoreName=*,alias=*", "read";
この権限は、すべてのキーストアへのアクセス権を付与します。アクセス権の範囲を制限するには、アスタリスクのワイルドカード(*)を、特定のアプリケーション・ストライプおよびキーストア名と置き換えます。ドライバは、キーストアを権限付きアクションとしてロードできません。これは、KeyStoreAccessPermission
もアプリケーションのコード・ベースに付与する必要があることを意味します。
9.6 Kerberosのサポート
この項では、次の項目について説明します。
9.6.1 JDBCによるKerberosのサポートの概要
Kerberosはネットワーク経由で認証ツールと強固な暗号化ツールを提供するネットワーク認証プロトコルです。Kerberosは秘密キー暗号化を使用する方式で、全社の情報システムのセキュリティ確保を容易に実現できます。Kerberosプロトコルは強固な暗号化を使用しているため、安全でないネットワーク接続を経由しても、クライアントまたはサーバーがサーバーまたはクライアントに対して身元を証明することができます。Kerberosを使用して身元を証明したクライアントおよびサーバーは、すべての通信を暗号化して、業務においてプライバシとデータ整合性を保全することができます。
Kerberosアーキテクチャでは、Key Distribution Center (KDC)と呼ばれる信頼できる認証サービスが軸となります。Kerberos環境のユーザーおよびサービスはプリンシパルと呼ばれ、各プリンシパルはKDCと秘密鍵(パスワードなど)を共有します。プリンシパルはHR
などのユーザーの場合も、データベース・サーバーのインスタンスの場合もあります。
12cリリース1以降、Oracle DatabaseではKerberosのレルム間認証もサポートしています。取得したレルムをKerberos構成ファイルのdomain_realms
セクションに適切に追加すると、ある特定のレルム内で、別のレルムのサービスにアクセスできます。
9.6.2 Kerberosを使用するためのWindowsの構成
klist、kinit
などのツールを提供する良質なKerberosクライアントは、次のリンクの場所にあります。
http://web.mit.edu/kerberos/dist/index.html
このクライアントでは便利なGUIも提供しています。
WindowsマシンでKerberosを構成するには、次の変更を行う必要があります。
- デスクトップで「マイ コンピュータ」アイコンを右クリックします。
- 「プロパティ」を選択します。「システムのプロパティ」ダイアログ・ボックスが表示されます。
- 「詳細」タブを選択します。
- 「環境変数」をクリックします。「環境変数」ダイアログ・ボックスが表示されます。
- 「新規」をクリックして新しい利用者変数を追加します。「新しいユーザー変数」ダイアログ・ボックスが表示されます。
- 「変数名」フィールドに「
KRB5CCNAME
」と入力します。 - 「変数値」フィールドに「
FILE:C:\Documents and Settings\
<user_name>
\krb5cc
」と入力します。 - 「OK」をクリックして「新しいユーザー変数」ダイアログ・ボックスを閉じます。
- 「OK」をクリックして「環境変数」ダイアログ・ボックスを閉じます。
- 「OK」をクリックして「システムのプロパティ」ダイアログ・ボックスを閉じます。
ノート:
C:\WINDOWS\krb5.ini
ファイルは、krb5.conf
ファイルと内容が同じです。
9.6.4 Kerberosを使用するコード例
次の例は、Oracle Database 12cリリース1 (12.1)のJDBC Thinドライバに含まれている新しいKerberos認証機能を示しています。このデモは、次の2つの使用例を説明しています。
-
最初のシナリオでは、OSがユーザー名と資格証明をメンテナンスします。資格証明はキャッシュに格納され、ドライバは資格証明を取得してからサーバーの認証を受けようとします。この使用例はモジュール
connectWithDefaultUser()
にあります。ノート:
-
デモのこの部分を実行する前に、次のコマンドを使用して、有効な資格証明を持っていることを確認してください。
> /usr/kerberos/bin/kinit client where, the password is welcome.
-
次のコマンドを使用してチケットをリストします。
> /usr/kerberos/bin/klist
-
-
2番目の使用例は、アプリケーションがユーザーの資格証明を制御する事例です。これは、複数のWebユーザーが各自の資格証明を持っているアプリケーション・サーバーの場合です。この使用例はモジュール
connectWithSpecificUser()
にあります。ノート:
このデモを実行するには、作業用の設定として、稼働中のKerberosサーバーと、Kerberos認証を使用するように構成されているOracle Databaseサーバーが必要です。例をコンパイルして実行するには、使用されている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=5221))(CONNECT_DATA=" + "(SERVICE_NAME=orcl)))"; 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"); } } } }
9.7 RADIUSのサポート
この項では、次の概念について説明します。
9.7.1 JDBCによるRADIUSのサポートの概要
Oracle Database 11gリリース1で、リモート認証ダイアルイン・ユーザー・サービス(RADIUS)が導入されました。RADIUSは、最も広く知られている、リモートでの認証とアクセスを可能にするクライアント/サーバー・セキュリティ・プロトコルです。Oracle Advanced Securityは、この標準をクライアント/サーバー・ネットワーク環境で使用して、RADIUSプロトコルをサポートするあらゆる認証方式の使用を可能にします。RADIUSは、トークン・カードやスマートカードなど、いろいろな認証メカニズムで使用できます。
9.7.3 RADIUSを使用するコード例
次の例は、Oracle Database 12cリリース1 (12.1)のJDBC Thinドライバに含まれている新しいRADIUS認証機能を示しています。作業用の設定として、稼働中のRADIUSサーバーと、RADIUS認証を使用するように構成されているOracle Databaseサーバーが必要です。例をコンパイルして実行するには、指定されている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=5221))(CONNECT_DATA=" + "(SERVICE_NAME=orcl)))"; 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(); } } }
9.8 セキュアな外部パスワード・ストアについて
アプリケーションがパスワード資格証明を使用してデータベースに接続する大規模なデプロイメントでの代替として、クライアント側のOracle Walletにそれらの資格証明を格納できます。Oracle Walletは、資格証明の認証および署名の格納に使用されるセキュアなソフトウェア・コンテナです。
クライアント側のOracleウォレットにデータベースのパスワード資格証明を格納すると、アプリケーション・コードやバッチ・ジョブ、スクリプトにユーザー名とパスワードを埋め込む必要がなくなります。このため、スクリプトやアプリケーション・コード内にパスワードが露出する危険性が減少し、ユーザー名やパスワードを変更するたびにコードを変更する必要がなくなるため、管理が単純化されます。また、アプリケーション・コードを変更する必要がないため、これらのユーザー・アカウントに対してパスワード管理ポリシーをさらに簡単に強制適用できるようになります。
oracle.net.wallet_location
接続プロパティを設定して、ウォレットの場所を指定できます。JDBCドライバは、このウォレットからユーザー名とパスワードのペアを取得できます。
関連項目:
-
セキュアな外部パスワード・ストアを使用するようにクライアントを構成する方法およびそのパスワード・ストア内の資格証明を管理する方法の詳細は、『Oracle Database管理者ガイド』を参照してください。
-
パスワード資格証明のためのセキュアな外部パスワード・ストアの管理方法の詳細は、『Oracle Databaseセキュリティ・ガイド』を参照してください。