对于最新的稳定版本,请使用 Spring Cloud Config 4.3.0spring-doc.cadn.net.cn

加密和解密

要使用加密和解密功能,您需要在 JVM 中安装全强度 JCE(默认情况下不包括在内)。 您可以从 Oracle 下载“Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files”,然后按照安装说明进行作(本质上,您需要将 JRE lib/security 目录中的两个策略文件替换为下载的文件)。

如果远程属性源包含加密内容(以{cipher}),它们在通过 HTTP 发送给客户端之前被解密。 此设置的主要优点是,当属性值处于“静态”状态时(例如,在 git 存储库中),它们不需要是纯文本的。 如果无法解密某个值,则会从属性源中删除该值,并添加具有相同键但前缀为invalid以及表示“不适用”的值(通常<n/a>). 这主要是为了防止密文被用作密码并意外泄露。spring-doc.cadn.net.cn

如果您为配置客户端应用程序设置远程配置存储库,它可能包含一个application.yml类似于以下内容:spring-doc.cadn.net.cn

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

中的加密值application.properties文件不得用引号括起来。否则,不会解密该值。以下示例显示了有效的值:spring-doc.cadn.net.cn

应用程序属性
spring.datasource.username: dbuser
spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ

您可以安全地将此纯文本推送到共享的 git 存储库,并且秘密密码仍然受到保护。spring-doc.cadn.net.cn

服务器还公开/encrypt/decrypt端点(假设这些端点是安全的并且仅由授权代理访问)。 如果编辑远程配置文件,则可以使用配置服务器通过将 POST 发送到/encrypt端点,如以下示例所示:spring-doc.cadn.net.cn

$ curl localhost:8888/encrypt -s -d mysecret
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
如果你使用 curl 进行测试,则使用--data-urlencode(而不是-d)并以要加密的值为前缀(curl 需要这个)或设置一个显式的=Content-Type: text/plain以确保 curl 在存在特殊字符时正确编码数据(“+”特别棘手)。
确保不要在加密值中包含任何 curl 命令统计信息,这就是示例使用-s让他们沉默的选项。将值输出到文件有助于避免此问题。

逆运算也可以通过以下方式进行/decrypt(前提是服务器是 配置了对称密钥或完整密钥对),如以下示例所示:spring-doc.cadn.net.cn

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

获取加密值并添加{cipher}前缀,然后再将其放入 YAML 或属性文件中,以及提交并将其推送到远程(可能不安全的)存储之前。spring-doc.cadn.net.cn

/encrypt/decrypt端点也都接受以下形式的路径/*/{application}/{profiles},当客户端调用主环境资源时,可用于在每个应用程序(名称)和每个配置文件的基础上控制加密。spring-doc.cadn.net.cn

若要以这种精细方式控制加密,还必须提供@Bean类型TextEncryptorLocator为每个名称和配置文件创建不同的加密器。 默认提供的加密不会这样做(所有加密都使用相同的密钥)。

spring命令行客户端(使用 Spring Cloud CLI 扩展 installed)也可用于加密和解密,如以下示例所示:spring-doc.cadn.net.cn

$ spring encrypt mysecret --key foo
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
$ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret

要使用文件中的密钥(例如用于加密的 RSA 公钥),请在前面添加 键值为“@”,并提供文件路径,如以下示例所示:spring-doc.cadn.net.cn

$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...
--key参数是强制性的(尽管有前缀)。--

解密错误

当配置服务器无法解密值时,它将创建一个invalid属性。spring-doc.cadn.net.cn

{
    "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
}

在上面的示例中,配置服务器无法解密SharedPasswordapplication-prd.yaml因此,配置服务器在属性名称前加上invalid.spring-doc.cadn.net.cn

如果配置客户端收到此响应,然后添加到应用的Environment和客户 请求SharedPassword它会得到Fill_me_in.spring-doc.cadn.net.cn

如果您不希望配置服务器为属性添加前缀,则无法解密 witinvalid然后你可以设置spring.cloud.config.server.encrypt.prefix-invalid-propertiesfalse.如果你这样做,那么来自 配置服务器将如下所示:spring-doc.cadn.net.cn

    "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
}

在这种情况下,如果配置客户端要收到上述响应并请求该值 之SharedPasswordEnvironment它将取回加密值,而不是Fill_me_in.spring-doc.cadn.net.cn