11 EDQ暗号化の構成
EDQの暗号化フレームワークでは、この章で説明するように、OCIボールトおよびスクリプトの実装とともにプラガブル・モジュールがサポートされるようになりました。
- EDQ拡張暗号化の概要
セキュリティを強化するために、EDQ構成に格納されている特定の情報が暗号化されます。 - プラガブル資格証明ストアの構成
EDQ構成で使用されるユーザー名とパスワード資格証明は通常、プロパティ・ファイルで定義されます。 - カスタムJava暗号化および資格証明ストア・モジュールの作成
バージョン12.2.1.4.4および14.1.2.0.0のEDQでは、暗号化および資格証明の検索用のプラガブル・モジュールがサポートされています。次の項では、カスタムJavaクラスを使用してモジュールを実装する方法について説明します。このカスタムJavaクラスは、ネイティブ・コードが必要という理由で一部のセキュリティ・ストアと対話するスクリプトを作成できない場合に必要になります。
強化されたEDQ暗号化の概要
セキュリティを強化するために、EDQ構成に格納されている特定の情報が暗号化されます。
-
director.properties
のデータベース・パスワード(オプション、Tomcatのみ) -
データ・ストアのパスワード
-
格納されている資格証明
-
Webプッシュ通知Vapid秘密キー
バージョン12.2.1.4.3までのEDQでは、暗号化はECBモードのAES暗号を使用し、PKCS5Paddingを指定して実行されます。最初の起動時に、新しいランダム・キーが生成されて格納されます。Tomcatでは、キーはファイルlocalhome/kfile
に格納され、WebLogicではキーはFMWキー・ストアに格納されます。
-
デフォルトのAESキー・サイズ(128ビット)が使用されます。セキュリティを強化するには、256ビットを使用する必要があります。
-
ECB暗号モードでは初期化ベクトル(IV)を使用しないため、同じ文字列を暗号化すると常に同じ結果が生成されます。そのため、攻撃者が暗号化された値を確認できれば、容易にパスワードを推測できます。
-
Tomcatでは、システムのどのユーザーでもキー・ファイルを読み取ることができます。
-
既存のスキーマを使用して新しいインストールを作成すると、新しいキー・ファイルが生成され、データベースにあって暗号化されている既存のデータはリカバリできません(この問題はOCIマーケットプレイス・イメージでも共通です)。
localhome/security/module.properties
によって構成されます。これには、モジュール・タイプを定義するタイプ・プロパティが含まれている必要があります。次のタイプがサポートされています。
- legacy -
module.properties
が存在しない場合にデフォルトで使用される現在のメカニズム。 - default - セキュリティが向上したレガシーモジュールのリファクタリング。
- ocivault - OCIボールトに格納されているキーを使用します。暗号化と復号化は、ボールト暗号化エンドポイントのコールによって実行されます。キーがボールトから離れることはないため、HSMまたはソフトウェア保護モードを使用できます。セキュリティを強化するためにキーをローテーションできます。データの暗号化するときにキー・バージョンを使用する復号化操作です。ボールト・シークレットを使用して資格証明ストアとして機能するように構成できます。
- script - 暗号化および復号化操作を実行するようにJavaScriptスクリプトを構成できます。これは、AWS Key Management Service (KMS)やGCP Cloud Key Management Serviceなどの追加のキー・フレームワークをサポートするために使用できます。このモジュールは、AWSやGCP Secrets Managerなどの外部サービスを使用して資格証明ストアとして機能するように構成することもできます。
- custom - カスタムJavaコード。詳細は、「カスタムJava暗号化および資格証明ストア・モジュールの作成」を参照してください。
デフォルト・セキュリティ・モジュール
- AESはランダムな初期化ベクトルを利用してGCMモードで使用されるため、同じデータを暗号化すると毎回異なる結果が返されます。
- 可能な場合は256ビット・キーが使用されます。
- Tomcatでは、キーはモード600 (-rw-------)に設定されたファイル
localhome/masterkey
に格納されます。
Ocivaultセキュリティ・モジュール
ocivaultセキュリティ・モジュール・タイプでは、OCIボールトに格納されているキーが使用されます。OCI APIのコールの認証では、プラットフォーム資格証明か、外部プロパティで構成された資格証明のいずれかを使用します。格納された資格証明はここでは使用できません。このモジュールを使用すると、起動時にEDQデータベース・スキーマのパスワードを復号化できるためです。
module.properties
の型には、次の追加プロパティが使用されます。
表11-1 Ocivaultセキュリティ・モジュールのプロパティ
プロパティ | 説明 |
---|---|
vault |
ボールト名またはOCID (必須)。 |
key |
キー名またはOCID (必須)。 |
region |
OCIリージョン名。省略した場合は、EDQインスタンスのリージョンが使用されます。 |
compartmentid |
ボールト・コンパートメントのOCID。ボールトまたはキーがOCIDで指定されていない場合に使用されます。省略した場合は、EDQインスタンスのコンパートメントが使用されます。 |
secrets.vault |
シークレット問合せのボールト名またはOCID。省略した場合は、キー・ボールトが使用されます。 |
secrets.encrypt |
ボールト・キーを使用してシークレット値を暗号化する場合、trueに設定します。シークレット値はOCIコンソールで表示できるため、コンソールに表示しないためには暗号化する必要があります。 |
secrets |
ボールト・シークレットを使用した資格証明の取得をサポートするには、trueに設定します。 |
auth.X |
OCI APIコールのオーセンティケータに渡される追加プロパティ。たとえば、 |
OCIモジュールの主なユース・ケースは、OCI APIコールの認証にプラットフォーム資格証明を使用できるコンピュート・インスタンスで使用する場合です。OCIダイナミック・グループが必要な権限を示している場合、追加の構成は必要ありません。
シークレット・ストレージ
モジュールでシークレットが使用可能になっている場合、外部統合の資格証明は、EDQ構成ファイルではなくボールトに格納できます。例としては、JMSブローカ接続、SMTP認証、LDAP資格証明があります。
シークレットを使用して資格証明を指定するには、ユーザー名およびパスワードのプロパティを次のように置き換えます。
cred.secret = secretname
この値のシークレット・ボールトは、次に示すように、usernameおよびpassword属性を含むJSON文字列である必要があります。
{ "username": "user1", "password": "mysecret2" }
モジュールのデフォルトのシークレット暗号化設定をオーバーライドするには、次の行を使用します。
cred.secret.encrypt = true | false
プレーンでユーザー名を指定し、ボールトからパスワードを取得するには、次の行を使用します。
cred.secret.username = username
こうすると、ボールトのシークレット値はパスワードのみになります。
ユーザー名が必要ない場合は、次の行を追加します。
cred.secret.passwordonly = true
こうすると、ボールトのシークレット値はパスワードのみになります。
OCI Vaultのmodule.properties構成の例
ローカル・コンパートメントとリージョンでプラットフォーム資格証明を使用する例:
type = ocivault
vault = edqvault
key = key1
secrets = true
secrets.encrypt = true
~/.oci/configからの資格証明でリモート・ボールトを使用する例:
type = ocivault
auth.profile = default
region = us-phoenix-1
compartmentid = compartmentid
vault = edqvault
key = key1
secrets = true
スクリプト・セキュリティ・モジュール
スクリプト・セキュリティ・モジュールのモジュール定義には、スクリプト・プロパティとしてスクリプト・ファイルの名前が含まれている必要があります。ファイルが絶対でない場合、EDQローカル構成ディレクトリを基準として検索されます。このスクリプトは、次の表に示す関数を定義します。
表11-2 スクリプト・セキュリティ・モジュールの関数
関数 | 必須 | 説明 |
---|---|---|
init(props) |
いいえ |
モジュールを初期化します。引数は、 |
encrypt(plain) |
はい |
プレーン・テキストを暗号化します。引数と結果はArrayBuffersです。 |
decrypt(plain) |
はい |
暗号文を復号化します。引数と結果はArrayBuffersです。 |
getCredentials(props) |
いいえ |
シークレット・ストアから資格証明を取得します。properties引数には、EDQ構成からのcred.*設定が含まれます。 |
init関数に渡されるプロパティには、「encryption」に設定された type値が含まれます。そのため、セキュリティ・モジュールおよび資格証明ストアと同じスクリプトを使用できます。
base64関連
外部暗号化APIでは、プレーン・テキストおよび暗号テキストにbase64エンコーディングが必要です。EDQスクリプトでは、次のbase64サポート関数を使用できます。
var encoder = BASE64.getEncoder()
var enc = encoder.encode(bytes) // Encode an ArrayBuffer to base64 string
var enc2 = encoder.encodeFromString(str) // Encode a string to base 64 string
var urlenc = BASE64.getUrlEncoder() // Encoder using URL-safe alphabet
var mimeenc = BASE64.getMimeEncoder() // Encoder with MIME line splitting
vat nopad = BASE64.getEncoder().withoutPadding() // Encoder which does not use = padding
var decoder = BASE64.getDecoder()
var dec = decoder.decode(string) // Decode a base64 string to ArrayBuffer
var dec2 = encoder.decodeToString(str) // Decode a base 64 string to a string
var urldec = BASE64.getUrlEncoder() // Decoder using URL-safe alphabet
var mimdec = BASE64.getMimeEncoder() // Decoder with MIME line splitting
サンプル・スクリプト
AWSキーおよびシークレット管理フレームワークを使用する例
module.properties
type = script
keyid = alias/rde1
region = eu-west-1
script = awsenc.js
secrets = true
auth.profile = myprofile
awsenc.js
// Script security module sample for AWS KMS and secrets manager
// =============================================================
//
// Required properties:
//
// region AWS region
// keyid KMS keyid or alias/name
//
// Optional:
//
// secrets Set to true for secrets support
//
// Configure proxy server with https.proxyHost and https.proxyPort properties
addLibrary("http")
addLibrary("logging")
var client
var secclient
var encoder = BASE64.getEncoder()
var decoder = BASE64.getDecoder()
var kmsurl
var keyid
var secrets = false
var secretenc = false
function init(props) {
// Authentication properties
var aprops = Object.keys(props).filter(k => k.startsWith("auth.")).reduce((o, k) => (o[k.substring(5)] = props[k], o), {})
// Client for KMS
client = HTTP.builder().withAWSAuthentication(aprops).build();
// Properties
var region = props.region
keyid = props.keyid
if (!region || !keyid) {
throw "awsenc: region or key not specified"
}
kmsurl = "https://kms." + region + ".amazonaws.com"
// Secrets handling
secrets = props.secrets == "true"
if (secrets) {
// URL and client for secret queries
securl = "https://secretsmanager." + region + ".amazonaws.com"
secclient = HTTP.builder().withAWSAuthentication(aprops).build();
}
}
function encrypt(plain) {
var req = client.requestbuilder().header("X-Amz-Target", "TrentService.Encrypt").build();
var res = req.post(kmsurl, JSON.stringify({KeyId: keyid, Plaintext: encoder.encode(plain)}), "application/x-amz-json-1.1")
return decoder.decode(JSON.parse(res.data).CiphertextBlob)
}
function decrypt(ctext) {
var req = client.requestbuilder().header("X-Amz-Target", "TrentService.Decrypt").build();
var res = req.post(kmsurl, JSON.stringify({keyId: keyid, CiphertextBlob: encoder.encode(ctext)}), "application/x-amz-json-1.1")
return decoder.decode(JSON.parse(res.data).Plaintext)
}
function getCredentials(props) {
if (secrets) {
var s = props.secret
if (s) {
var req = secclient.requestbuilder().failonerror(false).header("X-Amz-Target", "secretsmanager.GetSecretValue").build()
var res = req.post(securl, JSON.stringify({SecretId: s}), "application/x-amz-json-1.1")
if (res.code != 200) {
logger.log(Level.WARNING, "AWS secrets manager call failed with code {0}", res.code)
} else {
var obj = JSON.parse(res.data)
var str = obj.SecretString || decoder.decodeToString(obj.SecretBinary)
if (props["secret.passwordonly"] == "true") {
return {username: "", password: str}
} else {
var val = JSON.parse(str)
return {username: val.username, password: val.password}
}
}
}
}
return null
}
GCPキーおよびシークレット・フレームワークを使用する例
module.properties
type = script
script = gcpenc.js
project = green-wombat-4252311
keyfile = /opt/edq/gcp-encrypt.json
location = europe-west2
keyring = rde
key = rde1
secrets = true
seckeyfile = /opt/edq/gcp-secrets.json
gcpenc.js
// Script security module sample for GCP KMS and secrets manager
// =============================================================
//
// Required properties:
//
// project GCP project name
// location Key location (such as europe-west2)
// keyring Keyring name
// key Key name
// keyfile Service account key file location
//
// Optional:
//
// version Key version name
//
// Configure proxy server with https.proxyHost and https.proxyPort properties
addLibrary("http")
addLibrary("logging")
var client
var encoder = BASE64.getEncoder()
var decoder = BASE64.getDecoder()
var decurl
var encurl
var secrets = false
function init(props) {
// Need:
//
// project
// location
// keyring
// key
// keyfile
//
// Optional:
//
// version
if (!props.project || !props.location || !props.keyring || !props.key || !props.keyfile) {
throw "gcpenc: missing properties"
}
var project = props.project
var location = props.location
var base = "https://cloudkms.googleapis.com/v1"
+ "/projects/" + props.project
+ "/locations/" + props.location
+ "/keyRings/" + props.keyring
+ "/cryptoKeys/" + props.key
decurl = base + ":decrypt"
encurl = base
if (props.version) {
encurl += "/cryptoKeyVersions/" + props.version
}
encurl += ":encrypt"
// Client for KMS
client = HTTP.builder().withAuthentication("GCP", {keyfile: props.keyfile, claim_scope: "https://www.googleapis.com/auth/cloud-platform"}).build();
secrets = props.secrets == "true"
if (secrets) {
// URL and client for secret queries
securl = "https://secretmanager.googleapis.com/v1/projects/" + props.project + "/secrets/"
}
}
function encrypt(plain) {
var req = client.requestbuilder().build();
var res = req.post(encurl, JSON.stringify({"plaintext": encoder.encode(plain)}))
return decoder.decode(JSON.parse(res.data).ciphertext)
}
function decrypt(ctext) {
var req = client.requestbuilder().build();
var res = req.post(decurl, JSON.stringify({ciphertext: encoder.encode(ctext)}))
return decoder.decode(JSON.parse(res.data).plaintext)
}
function getCredentials(props) {
if (secrets) {
var s = props.secret
if (s) {
var url = securl + s + "/versions/latest:access"
var req = client.requestbuilder().failonerror(false).build()
var res = req.get(url)
if (res.code != 200) {
logger.log(Level.WARNING, "GCP secrets manager call failed with code {0}", res.code)
} else {
var obj = JSON.parse(res.data)
var str = decoder.decodeToString(obj.payload.data)
if (props["secret.passwordonly"] == "true") {
return {username: "", password: str}
} else {
var val = JSON.parse(str)
return {username: val.username, password: val.password}
}
}
}
}
return null
}
暗号化の移行
既存のシステムでセキュリティ・モジュールが置換または再構成されると、暗号化されたデータは使用できなくなります。システムが新規インストールで、director.properties
で暗号化が使用されていない場合、これは問題ではありません。既存の暗号化データがある場合は、移行REST APIを使用して新しいセキュリティ・モジュールを定義できます。
新しいシステム管理RESTエンドポイントが2つあります。
/edq/admin/security/migrateencryptionにPOST
ペイロードは、次の構造を持つJSONオブジェクトです。
{ "type" : "moduletype",
"properties": {
... other settings for the module ...
}
}
- ペイロードの定義を使用して、新しいセキュリティが作成および初期化されます。
- 既存の暗号化データは、現在のモジュールを使用して復号化され、新しいモジュールを使用して暗号化されます。
- 前述のステップが成功すると、新しいモジュールが現在のモジュールを置き換え、新しい定義でmodule.propertiesが書き込まれます。
移行コールの結果は、更新された項目を要約したレポートです。復号化できなかった項目があれば一覧表示されます。
URLに問合せパラメータ?dryrun=true
が含まれている場合、新しいモジュールが作成され、既存のデータの復号化がテストされますが、更新は行われません。
リモートOCI Vaultへの移行のペイロードの例
{ "type" : "ocivault",
"properties": {
"auth.profile" : "default",
"vault" : "rde",
"key" : "rtest",
"compartmentid" : "compartmentid",
"region" : "us-phoenix-1",
"secrets" : true,
"secrets.encrypt" : true
}
}
/etc/admin/security/rotateencryptionへのPOST
ペイロードは空のJSONオブジェクトです。既存の暗号化データは、現在のセキュリティ・モジュールを使用して復号化され、同じモジュールを使用して暗号化されます。古いバージョンを削除できるように、このコールは、新しいバージョンの作成後にボールト・キーで使用できます。
コールの結果は、移行コールのサマリーです。
URLに問合せパラメータ?dryrun=true
が含まれている場合、既存のデータの復号化がテストされますが、更新は行われません。
暗号化データを失わずに新しいOCIインスタンスで既存のスキーマを使用
新しいOCIインスタンスを作成しても、「既存のスキーマの使用」オプションを選択すると、新しいインスタンスはレガシー(またはデフォルト)のセキュリティ・モジュールで始まります。新しい秘密キーが作成され、既存の暗号化データにはアクセスできなくなります。データを保持するステップは、次のとおりです。
- 古いシステムを停止する前に、外部暗号化メカニズム(OCIボールトまたはAWS)を使用していることを確認してください。
- 新規システムを作成して設定します。
- 暗号化の移行を実行して、新しいシステムで外部モジュールを設定します。既存のデータの復号化は失敗します。現在のモジュールは異なるが、移行は完了後しているからです。暗号化されたデータは再度使用できます。
親トピック: EDQ暗号化の構成
プラガブル資格証明ストアの構成
EDQ構成で使用されるユーザー名とパスワード資格証明は通常、プロパティ・ファイルで定義されます。
director.properties
のデータベース・スキーマのパスワード- 「バケット」ファイルでのJMSブローカ認証
mail.properties
でのSMTP認証login.properties
でのLDAP認証
WebLogicでインスタンスを実行すると、資格証明はFMW資格証明ストア・フレームワークに格納されます。バージョン12.2.1.4.4以降のEDQの暗号化モジュール・メカニズムでは、セキュリティ・モジュールを資格証明ストアとして機能させることができますが、これは追加ストアの定義をサポートしていません。たとえば、ローカル暗号化メカニズムを使用して、OCI VaultsやAWS Secrets Managerなどの外部ストアから資格証明を取得することはできません。
追加の資格証明ストアの構成
バージョン12.2.1.4.4以降のEDQでは、追加の資格証明ストアを定義できるように暗号化モジュールが拡張されています。ストアは、localhome/security/credstores
ディレクトリにプロパティ・ファイルを追加することによって構成されます。各プロパティ・ファイルには、ストアタイプとそれに固有の追加設定とを定義する typeプロパティが含まれている必要があります。次のタイプがサポートされています。
- ocivault - 資格証明はシークレットとしてOCIボールトに格納され、値キーを使用して暗号化できます。
- script - JavaScriptスクリプトは、AWSやGCPシークレット・マネージャなどの外部サービスにコールアウトするように構成できます。
- custom - カスタムJavaクラス。
格納される資格証明は、関連付けられたファイル名のアルファベット順に問い合せられます。
Ocivault資格証明ストア
ocivaultセキュリティ・モジュール・タイプは、OCIボールトに格納されているシークレットを問い合せます。OCI APIのコールの認証では、プラットフォーム資格証明か、外部プロパティで構成された資格証明のいずれかを使用します。格納された資格証明はここでは使用できません。このモジュールを使用すると、起動時にEDQデータベース・スキーマのパスワードを問い合せることができるためです。
このタイプでは、次の追加プロパティが使用されます。
表11-3 Ocivault資格証明ストア
プロパティ | 説明 |
---|---|
vault |
ボールト名またはOCID (必須)。 |
secrets.encrypt |
ボールトからのキーを使用してシークレット値を暗号化する場合、trueに設定します。シークレット値はOCIコンソールで表示できるため、コンソールに表示しないためには暗号化する必要があります。 |
キー |
キー名またはOCID (secrets.encryptがtrueの場合は必須)。 |
region |
OCIリージョン名。省略した場合は、EDQインスタンスのリージョンが使用されます。 |
compartmentid |
ボールト・コンパートメントのOCID。ボールトまたはキーがOCIDで指定されていない場合に使用されます。省略した場合は、EDQインスタンスのコンパートメントが使用されます。 |
auth.X |
OCI APIコールのオーセンティケータに渡される追加プロパティ。たとえば、 |
OCIの主なユース・ケースは、OCI APIコールの認証にプラットフォーム資格証明を使用できるコンピュート・インスタンスで使用する場合です。OCIダイナミック・グループが必要な権限を示している場合、追加の構成は必要ありません。
シークレットの使用
ボールト・シークレットを使用して資格証明を指定するには、ユーザー名およびパスワードのプロパティを次のように置き換えます。
cred.secret = secretname
この値のシークレット・ボールトは、次に示すように、usernameおよびpassword属性を含むJSON文字列である必要があります。
{ "username": "user1", "password": "mysecret2" }
モジュールのデフォルトのシークレット暗号化設定をオーバーライドするには、次の行を使用します。
cred.secret.encrypt = true | false
プレーンでユーザー名を指定し、ボールトからパスワードを取得するには、次の行を使用します。
cred.secret.username = username
こうすると、ボールトのシークレット値はパスワードのみになります。
ユーザー名が必要ない場合は、次の行を追加します。
cred.secret.passwordonly = true
こうすると、ボールトのシークレット値はパスワードのみになります。
例
oci.properties
type = ocivault
secrets.encrypt = true
vault = vault1
key = rtest
compartmentid = ocid1.compartment.oc1..aaaaaaaaeq2s...
region = us-phoenix-1
スクリプト資格証明ストア
スクリプト資格証明ストアのプロパティには、スクリプト・ファイルの名前としてscriptプロパティが含まれている必要があります。ファイルが絶対でない場合、EDQローカル構成ディレクトリを基準として検索されます。このスクリプトは、次の機能を定義します。
表11-4 スクリプト資格証明ストア
関数 | 必須 | 説明 |
---|---|---|
init(props) |
いいえ |
モジュールを初期化します。引数は、プロパティ・ファイルのプロパティを含むオブジェクトです。 |
getCredentials(props) |
はい |
シークレット・ストアから資格証明を取得します。properties引数には、EDQ構成からのcred.*設定が含まれます。 |
init関数に渡されるプロパティには、「credentials」に設定された type値が含まれています。そのため、セキュリティ・モジュールおよび資格証明ストアと同じスクリプトを使用できます。
AWSシークレット管理フレームワークを使用する例
base64サポート関数の詳細は、「強化されたEDQ暗号化の概要」を参照してください。
aws.properties
type = script
region = eu-west-1
script = awscreds.js
auth.profile = myprofile
awscreds.js
// Script credentials module sample for AWS secrets manager
// =========================================================
//
// Required properties:
//
// region AWS region
//
// Configure proxy server with https.proxyHost and https.proxyPort properties
addLibrary("http")
addLibrary("logging")
var secclient
var encoder = BASE64.getEncoder()
var decoder = BASE64.getDecoder()
function init(props) {
// Authentication properties
var aprops = Object.keys(props).filter(k => k.startsWith("auth.")).reduce((o, k) => (o[k.substring(5)] = props[k], o), {})
// Properties
var region = props.region
if (!region) {
throw "awscreds: region not specified"
}
// URL and client for secret queries
securl = "https://secretsmanager." + region + ".amazonaws.com"
secclient = HTTP.builder().withAWSAuthentication(aprops).build();
}
function getCredentials(props) {
var s = props.secret
if (s) {
var req = secclient.requestbuilder().failonerror(false).header("X-Amz-Target", "secretsmanager.GetSecretValue").build()
var res = req.post(securl, JSON.stringify({SecretId: s}), "application/x-amz-json-1.1")
// Error 400 can mean secret not found, so don't report it
if (res.code != 200) {
if (res.code != 400) {
logger.log(Level.WARNING, "AWS secrets manager call failed with code {0}", res.code)
}
} else {
var obj = JSON.parse(res.data)
var str = obj.SecretString || decoder.decodeToString(obj.SecretBinary)
if (props["secret.passwordonly"] == "true" || props["secret.username"]) {
return {username: props["secret.username"] || "", password: str}
} else {
var val = JSON.parse(str)
return {username: val.username, password: val.password}
}
}
}
return null
}
親トピック: EDQ暗号化の構成
カスタムJava暗号化および資格証明ストア・モジュールの作成
バージョン12.2.1.4.4および14.1.2.0.0のEDQでは、暗号化および資格証明の検索用のプラガブル・モジュールがサポートされています。次の項では、カスタムJavaクラスを使用してモジュールを実装する方法について説明します。このカスタムJavaクラスは、ネイティブ・コードが必要という理由で一部のセキュリティ・ストアと対話するスクリプトを作成できない場合に必要になります。
カスタム・モジュールは、次に示すように定義されます。
type = custom
class = java class name
- 必要なインタフェースを実装するJavaクラスを作成します。
- クラスパスで
installdir/buildjars/customsecuritymodules.jar
を使用してクラスをコンパイルします。 localhome/security/jars
のjarファイルでクラスをパッケージ化します。
installdir/buildjars/customsecuritymodules.jar
のdocs
サブフォルダに含まれるインタフェースのJavadocを要約します。
カスタム暗号化モジュール
カスタム暗号化モジュールは、次に示すようにインタフェース oracle.edq.security.module.custom.interfaces.CustomEncryptionModuleを実装する必要があります。
CustomEncryptionModule
/*
* Copyright (C) 2023, Oracle and/or its affiliates. All rights reserved.
*/
package oracle.edq.security.module.custom.interfaces;
import java.nio.file.Path;
import java.util.Properties;
/**
* Interface implemented by custom encryption modules.
*/
public interface CustomEncryptionModule {
/**
* Initialize the encryption module.
*
* @param localconfig The local configuration area. This can be used to locate or store extra files
* required by the module.
* @param props The module properties
* @param persist If <code>true</code> the module data can be persisted for future use.
* This flag will be <code>false</code> if the module is being initalized for a "dryrun" encryption migration.
* In this case no permanent changes should be made in the file system.
*
* @throws Exception If initialization failed.
*/
void initEncryption(Path localconfig, Properties props, boolean persist) throws Exception;
/**
* Encrypt some data.
*
* @param in The plain text
*
* @return The cipher text
*
* @throws Exception If encryption failed
*/
byte [] encrypt(byte [] in) throws Exception;
/**
* Decrypt some data.
*
* @param in The cipher text
*
* @return The plain text
*
* @throws Exception If decryption failed
*/
byte [] decrypt(byte [] in) throws Exception;
}
暗号化モジュールがoracle.edq.security.module.custom.interfaces.CustomCredentialsModuleも実装している場合は、資格証明ストアとして機能します。この場合、initCredentialsメソッドはコールされません。
カスタム資格証明ストア
カスタム暗号化モジュールは、次に示すようにインタフェース oracle.edq.security.module.custom.interfaces.CustomCredentialsModuleを実装する必要があります。
CustomCredentialsModule
/*
* Copyright (C) 2023, Oracle and/or its affiliates. All rights reserved.
*/
package oracle.edq.security.module.custom.interfaces;
import java.nio.file.Path;
import java.util.Properties;
/**
* Interface implemented by custom credentials modules.
*/
public interface CustomCredentialsModule {
/**
* Get the prefix used to extract properties recognized by the module. The default value is "cred".
*
* @return The prefix
*/
default String credsPrefix() {
return "cred";
}
/**
* Initialize the credentials provider for credentials-only use.
*
* @param localconfig The local configuration area
* @param props The module properties
*
* @throws Exception If initialization failed.
*/
void initCredentials(Path localconfig, Properties props) throws Exception;
/**
* Attempt to get credentials.
*
* @param props The filtered property set.
*
* @return The credentials, or <code>null</code> if not found
*
* @throws Exception If an error ocurred
*/
Credentials getCredentials(Properties props) throws Exception;
/**
* Credentials result class.
*/
final class Credentials {
private String username;
private String password;
/**
* Constructor.
*
* @param username The user name
* @param password The password
*/
public Credentials(String username, String password) {
this.username = username;
this.password = password;
}
/**
* Get the user name.
*
* @return The user name
*/
public String getUsername() {
return username;
}
/**
* Get the password.
*
* @return The password
*/
public String getPassword() {
return password;
}
}
}
親トピック: EDQ暗号化の構成