14.5.1 在 Git 中加密属性
除了使用未加密的值外,Config Server 还支持在 Git 存储的配置文件中使用加密值。在 Git 存储中使用加密值的关键,实际上是一个密钥,一个用于加密的密钥。
要启用对属性加密,需要使用加密密钥。在将值传到客户端之前,使用密钥对加密值进行解密。Config Server 支持对称加密和非对称加密。设置对称加密的密钥,可在 Config Server 自身的配置中设置 encrypt.key 属性值。这个值可以用作加密和解密:
encrypt:
key: s3cr3t
在启动配置(例如 bootstrap.propertiesbootstrap.yml 中)中设置此属性非常重要。这样使 Config Server 对外提供服务之前,可以通过自动配置加载此属性。
为了提高安全性,您可以选择使用非对称加密密钥,如 RSA 密钥对或对 keystore 的引用。要创建这样的密钥对,可以使用 keytool 命令行工具:
$ keytool -genkeypair -alias tacokey -keyalg RSA \
-dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \
-keypass s3cr3t -keystore keystore.jks -storepass l3tm31n
生成的 keystore 将写入名为 keystore.jks 的文件中,可以选择把 keystore 文件保存在文件系统上,或将其放置在应用程序本身中。无论哪种情况,您都需要在 Config Server 的 bootstrap.yml 文件中,指定 keystore 文件的位置以及授权信息。
注意:要在 Config Server 中使用加密功能,必须安装 Java Cryptography Extensions Unlimited Strength 策略文件。详细信息请参阅 Oracle 的 Java SE 页:http://www.oracle.com/technetwork/java/javase/downloads/index.html
假设您选择将 keystore 打包到应用程序中,并放在类路径的根目录。然后就可以通过配置 Config Server 的以下属性使用 keystore:
encrypt:
key-store:
alias: tacokey
location: classpath:/keystore.jks
password: l3tm31n
secret: s3cr3t
有了密钥或 keystore,您现在需要一些加密的数据。Config Server 提供了 /encrypt 加密接口。所要做的就是通过 POST 请求,把一些要加密的数据发送到 /encrypt 接口。例如,假设您要加密 MongoDB 数据库的密码。使用 curl 可以这样加密这个密码:
$ curl localhost:8888/encrypt -d "s3cr3tP455w0rd"
93912a660a7f3c04e811b5df9a3cf6e1f63850cdcd4aa092cf5a3f7e1662fab7
提交 POST 请求后,您将收到一个加密值作为响应。剩下的就是复制该值,并将其粘贴到在 Git 存储库中保存的配置文件中。
要设置 MongoDB 密码,请在 application.yml 中添加 spring.data.mongodb.password 属性:
spring:
data:
mongodb:
password: '{cipher}93912a660a7f3c04e811b5df9a3cf6e1f63850...'
请注意,给 spring.data.mongodb.password 设置的值是用单引号(')引起来的,前缀为 {cipher}。这会让 Config Server 识别到,这是一个加密值,而不是普通的未加密值。
application.yml 的修改提交并推送到到 Git 存储库以后,Config Server 就准备好了提供加密属性服务。要查看它的运行情况,可使用 curl 模拟客户端调用:
$ curl localhost:8888/application/default | jq
{
"name": "app",
"profiles": [
"prof"
],
"label": null,
"version": "464adfd43485182e4e0af08c2aaaa64d2f78c4cf",
"state": null,
"propertySources": [
{
"name": "http://localhost:10080/tacocloud/tacocloudconfig/application.yml",
"source": {
"spring.data.mongodb.password": "s3cr3tP455w0rd"
}
}
]
}
如你所见,属性 spring.data.mongodb.password 的值是解密的形式。默认情况下,Config Server 提供的任何加密值,在后端 Git 存储库中都是加密的;它们在被使用之前会被解密。这意味着使用 Config Server 的客户端应用程序,不需要任何特殊的代码或配置来接收在 Git 中加密的属性。
如果您希望 Config Server 提供仍然加密的属性,您可以设置 spring.cloud.config.server.encrypt.enabled 属性为 false:
spring:
cloud:
config:
server:
git:
uri: http://localhost:10080/tacocloud/tacocloud-config
encrypt:
enabled: false
这将导致 Config Server 提供的所有属性值,包括加密属性值,与 Git 存储库中设置的值完全相同。再次使用 curl 命令模拟客户端调用,以显示禁用解密后的效果:
$ curl localhost:8888/application/default | jq
{
...
"propertySources": [
{
"name": "http://localhost:10080/tacocloud/tacocloudconfig/application.yml",
"source": {
"spring.data.mongodb.password": "{cipher}AQA4JeVhf2cRXW..."
}
}
]
}
当然,如果客户端接收到加密后的属性值,那么客户端现在就负责自行解密了。
尽管可以将加密的属性存储在 Git 中,再由 Config Server 提供服务。但我们已经看到加密并不是 Git 原生的能力,这需要您做一些工作,以便使用任何写入 Git 存储库的数据。而且,除非您的应用程序自行解密,否则使用 Config Server API 能够让任何人获取解密后的信息。让我们看看另一种配置 Config Server 的选择,它只为那些有权看到他们的使用方提供服务。
复制链接