加密和解密

要使用加密和解密功能,您需要在 JVM 中安裝完整強度的 JCE(預設不包含)。您可以從 Oracle 下載“Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files”,並按照安裝說明操作(實質上,您需要將 JRE lib/security 目錄中的兩個策略檔案替換為您下載的檔案)。這僅適用於舊版本的 Java。從 Java 9 開始,以及從 Java 8u161 及更高版本開始,無限強度加密預設啟用。

如果遠端屬性源包含加密內容(以 {cipher} 開頭的值),它們會在透過 HTTP 傳送給客戶端之前被解密。這種設定的主要優點是屬性值在“靜止”狀態時(例如,在 git 倉庫中)不需要是明文。如果某個值無法解密,它將從屬性源中移除,並新增一個具有相同鍵但字首為 invalid 的附加屬性,其值為“不適用”(通常為 <n/a>)。這主要是為了防止密文被用作密碼並意外洩露。

如果您為配置客戶端應用程式設定了一個遠端配置倉庫,它可能包含一個類似以下的 application.yml

application.yml
spring:
  datasource:
    username: dbuser
    password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'

application.properties 檔案中的加密值不能用引號括起來。否則,該值將不被解密。以下示例顯示了可行的值:

application.properties
spring.datasource.username: dbuser
spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ

您可以安全地將此明文推送到共享 git 倉庫,並且秘密密碼仍然受到保護。

伺服器還暴露了 /encrypt/decrypt 端點(假設這些端點是安全的,並且只有經過授權的代理才能訪問)。如果您編輯遠端配置檔案,您可以使用配置伺服器透過 POST 到 /encrypt 端點來加密值,如下例所示:

$ curl localhost:8888/encrypt -s -d mysecret
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
如果您使用 curl 進行測試,請使用 --data-urlencode(而不是 -d),並用 = 作為加密值的字首(curl 需要此操作),或者設定一個顯式的 Content-Type: text/plain,以確保在存在特殊字元(特別是 '+' 字元很棘手)時 curl 能正確編碼資料。
請確保不要將任何 curl 命令統計資訊包含在加密值中,這就是示例中使用 -s 選項來抑制它們的原因。將值輸出到檔案可以幫助避免此問題。

透過 /decrypt 也可以執行反向操作(前提是伺服器配置了對稱金鑰或完整的金鑰對),如下例所示:

$ curl localhost:8888/decrypt -s -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret

獲取加密值,並在將其放入 YAML 或屬性檔案之前,以及在提交併將其推送到遠端(可能不安全)儲存之前,新增 {cipher} 字首。

/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.yamlSharedPassword 的值,因此配置伺服器將屬性名稱加上了 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

© . This site is unofficial and not affiliated with VMware.