Encryption and Decryption

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

如果远程属性源包含加密内容(以 {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 端点(假设这些端点是安全的,并且仅由经过授权的代理程序访问)。如果您编辑远程配置文件,您可以使用 Config Server 通过对 /encrypt 端点 POST,来加密值,如下例所示:

$ 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 参数是强制性的(尽管带有 -- 前缀)。