> For the complete documentation index, see [llms.txt](https://potoyang.gitbook.io/spring-in-action-v5/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://potoyang.gitbook.io/spring-in-action-v5/di-14-zhang-pei-zhi-guan-li/14.5-wei-pei-zhi-de-shu-xing-jia-mi/14.5.1-zai-git-zhong-jia-mi-shu-xing.md).

# 14.5.1 在 Git 中加密属性

除了使用未加密的值外，Config Server 还支持在 Git 存储的配置文件中使用加密值。在 Git 存储中使用加密值的关键，实际上是一个密钥，一个用于加密的密钥。

要启用对属性加密，需要使用加密密钥。在将值传到客户端之前，使用密钥对加密值进行解密。Config Server 支持对称加密和非对称加密。设置对称加密的密钥，可在 Config Server 自身的配置中设置 `encrypt.key` 属性值。这个值可以用作加密和解密：

```yaml
encrypt:
  key: s3cr3t
```

在启动配置（例如 `bootstrap.properties` 或 `bootstrap.yml` 中）中设置此属性非常重要。这样使 Config Server 对外提供服务之前，可以通过自动配置加载此属性。

为了提高安全性，您可以选择使用非对称加密密钥，如 RSA 密钥对或对 keystore 的引用。要创建这样的密钥对，可以使用 keytool 命令行工具：

```bash
$ 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：

```yaml
encrypt:
  key-store:
    alias: tacokey
    location: classpath:/keystore.jks
    password: l3tm31n
    secret: s3cr3t
```

有了密钥或 keystore，您现在需要一些加密的数据。Config Server 提供了 `/encrypt` 加密接口。所要做的就是通过 POST 请求，把一些要加密的数据发送到 `/encrypt` 接口。例如，假设您要加密 MongoDB 数据库的密码。使用 curl 可以这样加密这个密码：

```bash
$ curl localhost:8888/encrypt -d "s3cr3tP455w0rd"
93912a660a7f3c04e811b5df9a3cf6e1f63850cdcd4aa092cf5a3f7e1662fab7
```

提交 POST 请求后，您将收到一个加密值作为响应。剩下的就是复制该值，并将其粘贴到在 Git 存储库中保存的配置文件中。

要设置 MongoDB 密码，请在 `application.yml` 中添加 `spring.data.mongodb.password` 属性：

```yaml
spring:
  data:
    mongodb:
      password: '{cipher}93912a660a7f3c04e811b5df9a3cf6e1f63850...'
```

请注意，给 `spring.data.mongodb.password` 设置的值是用单引号(`'`)引起来的，前缀为 `{cipher}`。这会让 Config Server 识别到，这是一个加密值，而不是普通的未加密值。

对 `application.yml` 的修改提交并推送到到 Git 存储库以后，Config Server 就准备好了提供加密属性服务。要查看它的运行情况，可使用 curl 模拟客户端调用：

```bash
$ 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:

```yaml
spring:
  cloud:
    config:
      server:
        git:
          uri: http://localhost:10080/tacocloud/tacocloud-config
        encrypt:
          enabled: false
```

这将导致 Config Server 提供的所有属性值，包括加密属性值，与 Git 存储库中设置的值完全相同。再次使用 curl 命令模拟客户端调用，以显示禁用解密后的效果：

```bash
$ 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 的选择，它只为那些有权看到他们的使用方提供服务。
