暗号化と復号化
| 暗号化および復号化機能を使用するには、JVM に完全強度の JCE がインストールされている必要があります(デフォルトでは含まれていません)。Oracle から "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" をダウンロードし、インストール手順に従ってください(基本的に、JRE の lib/security ディレクトリにある 2 つのポリシーファイルをダウンロードしたものに置き換える必要があります)。これは古いバージョンの Java にのみ適用されます。Java 9 以降、Java 8u161 以降では、無制限強度の暗号化がデフォルトで有効になっています。 |
リモートプロパティソースに暗号化されたコンテンツ({cipher} で始まる値)が含まれている場合、HTTP 経由でクライアントに送信する前に復号化されます。この設定の主な利点は、プロパティ値が「静止」しているとき(たとえば、git リポジトリ内)にプレーンテキストである必要がないことです。値を復号化できない場合は、プロパティソースから削除され、同じキーが接頭辞として invalid と「該当なし」を意味する値(通常は <n/a>)が付いた追加のプロパティが追加されます。これは主に、暗号文がパスワードとして使用され、誤って漏洩するのを防ぐためです。
構成クライアントアプリケーション用にリモート構成リポジトリをセットアップする場合、次のような application.yml が含まれている可能性があります。
spring:
datasource:
username: dbuser
password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'application.properties ファイルの暗号化された値は、引用符で囲むことはできません。それ以外の場合、値は復号化されません。次の例は、機能する値を示しています。
spring.datasource.username: dbuser
spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJこのプレーンテキストを共有 git リポジトリに安全にプッシュでき、シークレットパスワードは保護されたままになります。
サーバーは、/encrypt および /decrypt エンドポイントも公開します(これらが保護されており、認可されたエージェントによってのみアクセスされることを前提としています)。リモート構成ファイルを編集する場合、次の例に示すように、構成サーバーを使用して、/encrypt エンドポイントに POST することで値を暗号化できます。
$ curl localhost:8888/encrypt -s -d mysecret 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
curl でテストしている場合は、(-d の代わりに) --data-urlencode を使用し、値のプレフィックスを付けて = で暗号化するか(curl ではこれが必要)、明示的な Content-Type: text/plain を設定して、特殊文字('+')がある場合に curl がデータを正しくエンコードするようにします。特に注意が必要です)。 |
暗号化された値に curl コマンド統計を含めないように注意してください。これが、例で -s オプションを使用して無音にする理由です。値をファイルに出力すると、この問題を回避できます。 |
次の例に示すように、逆の操作は /decrypt を介して利用することもできます(サーバーが対称鍵または完全鍵ペアで構成されている場合)。
$ curl localhost:8888/decrypt -s -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda mysecret
暗号化された値を取得し、{cipher} プレフィックスを追加してから、YAML またはプロパティファイルに配置し、コミットしてリモート(安全でない可能性がある)ストアにプッシュします。
/encrypt エンドポイントと /decrypt エンドポイントはどちらも、/*/{application}/{profiles} の形式のパスを受け入れます。これを使用して、クライアントがメイン環境リソースを呼び出すときに、アプリケーションごと(名前)ごとおよびプロファイルごとに暗号化を制御できます。
このきめ細かい方法で暗号化を制御するには、名前とプロファイルごとに異なる暗号化機能を作成する型 TextEncryptorLocator の @Bean も提供する必要があります。デフォルトで提供されているものはそうしません(すべての暗号化は同じキーを使用します)。 |
次の例に示すように、spring コマンドラインクライアント(Spring Cloud CLI 拡張機能がインストールされている)を使用して、暗号化と復号化を行うこともできます。
$ spring encrypt mysecret --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda $ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda mysecret
次の例に示すように、ファイル内のキー(暗号化用の RSA 公開鍵など)を使用するには、キー値の前に "@" を付け、ファイルパスを指定します。
$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...--key 引数は必須です(-- プレフィックスがあるにもかかわらず)。 |
復号エラー
構成サーバーが値の復号化に失敗すると、HTTP レスポンスに invalid プロパティが作成されます。
次に例を示します
{
"label": null,
"name": "application",
"profiles": [
"prd"
],
"propertySources": [
{
"name": "file:/demo/configserver/application-prd.yaml",
"source": {
"invalid.SharedPassword": "<n/a>"
}
},
{
"name": "file:/demo/configserver/application.yaml",
"source": {
"SharedPassword": "Fill_me_in"
}
}
],
"state": null,
"version": null
} 上記の例では、構成サーバーは application-prd.yaml 内の SharedPassword の値を復号化できなかったため、構成サーバーはプロパティ名に invalid というプレフィックスを付けました。
このレスポンスが 構成クライアントによって受信され、アプリの Environment に追加され、クライアントが SharedPassword の値をリクエストした場合、Fill_me_in が取得されます。
構成サーバーが invalid で復号化できないプロパティにプレフィックスを付けないようにするには、spring.cloud.config.server.encrypt.prefix-invalid-properties を false に設定します。これを行うと、構成サーバーからの同じレスポンスは次のようになります。
"label": null,
"name": "application",
"profiles": [
"prd"
],
"propertySources": [
{
"name": "file:/demo/configserver/application-prd.yaml",
"source": {
"SharedPassword": "AYBKlpcZpaR36OcRDQjNIQl6fmnddAQhetMw/uyTpnn5fDj+unJ9QOEbqiPc9fX0N+CC8i+EJiN6nlH9Xqu6sH1tX/P6zg1CIy+ct/1RWGNbmQ256jc6vQaXhiN8sA8Mr6QiqYnMoBd+Jni/Miir5G3a7G9MmjbEUASKJOhUlIFKqL1IqB81RBT/cv0bg9kAiy5VBF1WppxP/PwtjECzbeUi2Y1jbpYb98rnc/qmRO3ZJam9fDNcPpW09qGFhGgJIujca257F7G4guS2w/7haVzNoyRiwHzZ14oL8AIxHLMBSJJF19ULlsMAkROj9o9TnwhL9r4rX9sAWk28c5eq77+iVpmlT3yoRdZqvMqffzKiibDlzz95Gmms7V7mctxrhNVOOWTwMSJvk94Y9ZPenljKgPJIV3Z1cqqx+W8JxFFeelOuYvMEe4bOVBh1TepGzzdWVdYbylgXJy35uRTZ2drybUe5+jc0hiAuujHz0zdY1FwOHfwzSsSidlYn4syPeuytnxTzn7fbWXeXetTTtDlmLRf8MBSzXzDFWNH0cNGOCQ=="
}
},
{
"name": "file:/demo/configserver/application.yaml",
"source": {
"SharedPassword": "Fill_me_in"
}
}
],
"state": null,
"version": null
} この場合、構成クライアントが上記のレスポンスを受信し、Environment から SharedPassword の値をリクエストすると、Fill_me_in ではなく暗号化された値が返されます。