常に機密機能を使用してデータベーステーブルの特定のデータ列のデータを暗号化し、Javaアプリケーションを使用してデータベースに接続する場合は、EncJDBCを使用できます。 これにより、データベース接続が容易になり、常に機密機能の使用が簡単になります。 このトピックでは、EncJDBCを使用して常に機密のデータベースに接続する方法について説明します。
必要なマスター暗号化キー (MEK) がある場合、EncJDBCは暗号文データを自動的に復号し、平文データを返すことができます。 このプロセスはアプリケーションに対して透過的であり、アプリケーションコードをいくつか変更することで、アプリケーションを常に機密のデータベースに接続できます。 これにより、常に機密機能の使用が簡単になります。
前提条件
常に機密機能が有効になっています。 詳細については、「常に機密機能の有効化」をご参照ください。
常時機密機能が有効になっているRDSインスタンスに関する接続情報が取得されます。 接続情報には、ドメイン名 (ホスト) 、ポート番号 (ポート) 、インスタンス名 (dbname) 、ユーザー名 (ユーザー名) 、パスワード (パスワード) が含まれます。
データ保護ルールが設定されています。 詳細については、「データ保護ルールの設定」をご参照ください。
使用上の注意
MEK
を保存し、機密保持する必要があります。JDK 1.8以降が使用されます。
説明このトピックでは、Mavenのバージョンは
3.9.2
で、開発ツールはIntelliJ IDEA Community Edition 2022.3.2
です。
手順
ステップ1: Maven依存関係の追加
Mavenのプロジェクトのpom.xmlファイルに次の依存関係を追加します。
<dependencies>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-encdb-mysql-jdbc</artifactId>
<version>1.0.5</version>
</dependency>
</dependencies>
手順2: サンプルコードに基づくEncJDBCの設定
JDBCと同じ方法でEncJDBC
を使用できます。 EncJDBC
を使用する前に、データセキュリティのためにEncJDBCでMEK
やENC_ALGO
などの必要なパラメーターを設定する必要があります。 MEKはマスター暗号化キーを指定し、ENC_ALGOは暗号化アルゴリズムを指定する。
次の表に、パラメーターと値の例を示します。
パラメーター | 例 (文字列型) | 説明 |
MEK | 00112233445566778899aabbccddeeff | データ所有者によって指定されたMEK。 MEK生成: OpenSSLやopenssl rand -hex 16などのパスワード生成ツールを使用したり、プログラミング言語でランダム関数を呼び出したり、Key Management Service (KMS) からキーを取得したりできます。 有効値: 長さが32文字の16バイトの16進文字列。 警告 MEKは、暗号化されたデータへのアクセスに使用するルート資格です。 セキュリティ上の理由から、常時機密機能が有効になっているRDSインスタンスは、MEKを生成、保存、またはバックアップしません。 MEKを生成し、機密を保持する必要があります。 MEKを紛失した場合、MEKを使用して暗号化されたデータにアクセスできなくなります。 MEKをバックアップすることをお勧めします。 |
ENC_ALGO | SM4_128_CBC | データを保護するために使用される暗号化アルゴリズム。 有効な値:
説明
|
MEKおよびENC_ALGOパラメーターの設定
次のセクションでは、MEK
パラメーターとENC_ALGO
パラメーターの設定に使用できる方法について説明します。 JDBCでパラメーターを設定するために2つ以上のメソッドを使用する場合は、JDBCプロパティの設定、設定ファイル、およびURLの設定の順序で優先されます。
複数のパラメーターを連結するには、アンパサンド (
&
) を使用できます。次の方法では、
MEK
はクライアント側のオンプレミスマシンで構成され、エンベロープ暗号化を使用してサーバーに配布され、MEK
が漏洩しないようにします。
JDBCプロパティの設定
標準JDBCからRDSインスタンスに接続する場合、[プロパティ]
設定を構成する必要があります。 サンプルコード:
// ドメイン名 (ホスト名) 、ポート番号 (ポート) 、インスタンス名 (dbname) 、ユーザー名 (ユーザー名) 、パスワード (パスワード) などの接続情報を取得します。
//...
String mek=...;
String encAlgo=...;
Properties props = new Properties();
props.setProperty("user" 、username);
props.setProperty("password" 、password);
props.setProperty("MEK" 、mek);
props.setProperty("ENC_ALGO" 、encAlgo);
String dbUrl = String.format("jdbc:mysql:encdb:// % s:% s/% s" 、ホスト名、ポート、dbname);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
接続接続=DriverManager.getConnection(dbUrl、props);
//... クエリを開始...
構成ファイルの使用
設定ファイルを作成し、設定ファイルでMEKなどの必要なパラメーターを設定できます。 次に、プロジェクトでencJdbcConfigFileという名前のプロパティを指定し、プロパティの値を構成ファイルのディレクトリに設定できます。 ディレクトリを指定しない場合、デフォルトでencjdbc.conf
ファイルが使用されます。
設定ファイルの内容:
MEK=
ENC_ALGO=
設定ファイルのディレクトリは、次の方法で指定できます。
構成ファイルをプロジェクトのresourcesディレクトリに格納します。
構成ファイルをプロジェクトのルートディレクトリに格納します。 ルートディレクトリは、実行時にアプリケーションによって使用されるディレクトリです。
ファイル設定が完了したら、アプリケーションで追加の設定を構成する必要はありません。
// ドメイン名 (ホスト名) 、ポート番号 (ポート) 、インスタンス名 (dbname) 、ユーザー名 (ユーザー名) 、パスワード (パスワード) などの接続情報を取得します。
//...
String dbUrl = String.format("jdbc:mysql:encdb:// % s:% s/% s" 、ホスト名、ポート、dbname);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
接続接続=DriverManager.getConnection(dbUrl、ユーザー名、パスワード);
//... クエリを開始...
URLの設定
URLでMEK
パラメーターとENC_ALGO
パラメーターを設定できます。
// ドメイン名 (ホスト名) 、ポート番号 (ポート) 、インスタンス名 (dbname) 、ユーザー名 (ユーザー名) 、パスワード (パスワード) などの接続情報を取得します。
//...
String mek=...;
String encAlgo=...;
String dbUrl = String.format("jdbc:mysql:encdb:// % s:% s/% s?MEK=% s&ENC_ALGO=% s" 、ホスト名、ポート、dbname、mek、encAlgo);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
接続接続=DriverManager.getConnection(dbUrl、ユーザー名、パスワード);
//... クエリを開始...
JDBCプロパティ設定の完全なサンプルコード
// ドメイン名 (ホスト名) 、ポート番号 (ポート) 、インスタンス名 (dbname) 、ユーザー名 (ユーザー名) 、パスワード (パスワード) などの接続情報をインスタンス情報に更新します。
文字列hostname = "hostname";
String port = "port";
文字列dbname = "db";
文字列username = "user";
文字列password = "password";
String mek="00112233445566778899aabbccddeeff"; // これは値の例です。 より複雑なMEKを使用することをお勧めします。
文字列encAlgo="SM4_128_CBC";
Properties props = new Properties();
props.setProperty("user" 、username);
props.setProperty("password" 、password);
props.setProperty("MEK" 、mek);
props.setProperty("ENC_ALGO" 、encAlgo);
String dbUrl = String.format("jdbc:mysql:encdb:// % s:% s/% s" 、ホスト名、ポート、dbname);
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
接続接続=DriverManager.getConnection(dbUrl、props);
int[] intData = {1, 2, 3, 4, 5, 6};
String[] strData = {"abc", "bcd", "1", "def", "efg", "fgi"};
// テーブルの作成
connection.createStatement().exe cuteUpdate("ドロップテーブルif exists test");
connection.createStatement().exe cuteUpdate("テーブルテストの作成 (int、bテキスト)");
// データの挿入
for (int i = 0; i < 6; i ++) {
PreparedStatement pstmt = connection.prepareStatement("insert into test values (?,?)");
pstmt.setInt(1, intData[i]);
pstmt.setString(2, strData[i]);
pstmt.exe cuteUpdate();
}
// 平文データのチェック
ResultSet rs = connection.createStatement().exe cuteQuery("select * from test");
while (rs.next()) {
for (int i = 0; i < rs.getMetaData().getColumnCount(); i ++) {
System.out.print(rs.getString(i + 1));
System.out.print("\t");
}
System.out.print("\n");
}
出力:
1 abc
2 bcd
3 cde
4 def
5 efg
6 fgi
FAQ
スレッド "main" java.lang.IllegalAccessErrorの例外が
ある場合はどうすればよいですか: モジュールjava.baseがcom.sun.cryptoを無名モジュール @ 0x5c0369c 4
にエクスポートしないため、clas s com.alibaba.encdb.com mon.SymCrypto (無名モジュール @ 0x5c0369c4) クラスcom.sun.crypto.provider.SunJCE (モジュールjava.base) にアクセスできません。このエラーメッセージは、JDKバージョンが必要なバージョンよりも新しい場合に発生するモジュール間のアクセス許可の問題が原因で表示されることがあります。 このエラーを解決するには、プログラムを実行してcom.sun.crypto.providerをUNNAMEDモジュールにエクスポートするときに、VMオプション
-- add-exports=java.base/com.sun.crypto.provider=ALL-Unnamed
を追加する必要があります。がmekの規定に失敗した場合の対処方法: mekの設定が正しくない可能性があります。 詳細: プログラムを実行するとgcmEncryptエラー
メッセージが表示されますか?このエラーは、Oracle JDKの一般的なエラーです。 エラーを解決するには、次のいずれかの方法を使用します。
代わりにAmazon Correttoを使用します。
Oracle JDKを使用する場合は、次の手順を実行してセキュリティプロバイダーを構成する必要があります。
JDKのインストールパスを見つけます。
インストールパス /conf/security/
ディレクトリで、java.security
ファイルを見つけます。java.security
ファイルを編集します。[プロバイダーのリストとその優先順位 (上記参照)]
セクションで、次のコンテンツを追加します。security.provider.14=org.bouncycastle.jce.provider.BouncyCastleProvider