Secrets in Configuration

使用加密的配置值来保护敏感的密码、机密、令牌和密钥。

Use encrypted configuration values to protect sensitive passwords, secrets, tokens and keys.

可以在 ${handler::value} 中表示一个机密配置,其中 handler 是解码或解密 valueio.smallrye.config.SecretKeysHandler 的名称。

A secret configuration may be expressed as ${handler::value}, where the handler is the name of a io.smallrye.config.SecretKeysHandler to decode or decrypt the value.

Encrypt Configuration values

要加密并随后解密配置值,请添加以下受管依赖项:

To encrypt and later decrypt configuration values, add the following managed dependency:

pom.xml
<dependency>
    <groupId>io.smallrye.config</groupId>
    <artifactId>smallrye-config-crypto</artifactId>
</dependency>

使用 Quarkus CLI 命令添加一个新的加密值或加密 application.properties 中的现有值:

Use the Quarkus CLI command to add a new encrypted value or encrypt an existent value in application.properties:

CLI
quarkus config set --encrypt --name=my.secret --value=1234

For more information about how to install the Quarkus CLI and use it, please refer to the Quarkus CLI guide.

配置属性 my.secret 将添加到 application.properties,其中值 1234Base64 加密并编码以及表达式 ${aes-gcm-nopadding::} 连同必要的机密处理程序以解密值。如果不存在,还将生成加密密钥并将其设置到 smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key

The configuration property my.secret will be added to application.properties with the value 1234 encrypted and encoded in Base64 and an expression ${aes-gcm-nopadding::}, with the required secret handler to decrypt the value. If it doesn’t exist, an encryption key is also generated and set into smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key.

my.secret=${aes-gcm-nopadding::DLTb_9zxThxeT5iAQqswEl5Dn1ju4FdM9hIyVip35t5V}

smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key=DDne5obnfH1RSeTg71xSZg

默认的机密处理程序使用 AES/GCM/NoPadding 算法并要求表达式 ${aes-gcm-nopadding::value} 来解密 value

The default secret handler uses the AES/GCM/NoPadding algorithm and requires the expression ${aes-gcm-nopadding::value} to decrypt the value.

Read Encrypted Configuration

Quarkus 配置系统在查找 my.secret 时将自动解密配置值。

Quarkus configuration system, will automatically decrypt the configuration value when looking up my.secret.

用于对值进行加密的加密密钥必须与用于解密该值并设置为`smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key`的密钥相同。

The encryption key used to encrypt the value must be the same used to decrypt the value and set into smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key.

class BusinessBean {
    @Inject
    SmallRyeConfig config;

    public void businessMethod() {
        ConfigValue mySecret = config.getConfigValue("my.secret");
        mySecret.getValue(); 1
    }
}
1 Returns the value 1234.

Store secrets in a Keystore

虽然拥有加密值比明文值好,但仍然希望避免将其设置在`application.properties`中。

While having encrypted values, is better than plain values, we would still like to avoid having these set up in application.properties.

Java KeyStore 用于作为一个基于文件的`Vault`。敏感数据可以导入此`Vault`中,并安全地存储在其中(以 Java`SecretKey`值的形式)。要使用`KeyStore``ConfigSource`,请添加以下受管理的依赖关系:

Java KeyStore is used as a file-based Vault. Sensitive data can be imported to and securely stored in this Vault as Java SecretKey values. To use the KeyStore ConfigSource add the following managed dependency:

<dependency>
    <groupId>io.smallrye.config</groupId>
    <artifactId>smallrye-config-source-keystore</artifactId>
</dependency>

Create a KeyStore

以下命令创建了一个简单的 KeyStore:

The following command creates a simple KeyStore:

echo DLTb_9zxThxeT5iAQqswEl5Dn1ju4FdM9hIyVip35t5V | keytool -importpass -alias my.secret -keystore properties -storepass arealpassword -storetype PKCS12 -v

-alias my.secret`选项使用值`DLTb_9zxThxeT5iAQqswEl5Dn1ju4FdM9hIyVip35t5V`将配置属性名称`my.secret`存储在 KeyStore 中。-storepass arealpassword`是访问密钥库所需的密码。

The -alias my.secret option stores the configuration property name my.secret in the KeyStore with the value DLTb_9zxThxeT5iAQqswEl5Dn1ju4FdM9hIyVip35t5V. The -storepass arealpassword is the password required to access the keystore.

我们还需要安全地存储加密密钥。您不应该将该密钥与其他机密一起存储,因此我们可以为该密钥创建另一个`KeyStore`:

We also need to safely store the encryption key. You shouldn’t store the key with the rest of the secrets, so we can create another KeyStore for the key:

echo DDne5obnfH1RSeTg71xSZg | keytool -importpass -alias smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key -keystore key -storepass anotherpassword -storetype PKCS12 -v

Use the KeyStore

要使用新创建的`KeyStore`s, add the following configuration to application.properties

To use the newly created KeyStore`s, add the following configuration to `application.properties:

smallrye.config.source.keystore."properties".path=properties 1
smallrye.config.source.keystore."properties".password=arealpassword 2
smallrye.config.source.keystore."properties".handler=aes-gcm-nopadding 3

smallrye.config.source.keystore."key".path=key 4
smallrye.config.source.keystore."key".password=anotherpassword 5
1 The path to the ´KeyStore` with properties secrets
2 The KeyStore password to be able to extract the KeyStore secrets
3 The SecretKeyHandler to decrypt the KeyStore secrets
4 The path to the ´KeyStore` with encryption key.
5 The KeyStore password to be able to extract the encryption key

Protect the KeyStore password

您必须在`application.properties`中指定`KeyStore` 密码,才能让 Quarkus 从密钥库提取秘密。此密钥库密码是一个敏感值,因此您应考虑如何最大程度减少泄漏它的风险以及如何对其进行保护。

You need to specify a KeyStore password in application.properties for Quarkus be able to extract secrets from the keystore. This keystore password is a sensitive value, and therefore you should consider how to minimize a risk of leaking it and how to protect it.

您应当意识到的一件重要事情是,泄漏此密码并不一定意味着存储在密钥库中的实际机密也会泄漏,因为未经授权的人还需要访问实际密钥库文件。将对密钥库文件的访问限制为少数角色,并让 Quarkus 进程运行在其中一个角色中,将使该组之外的任何人更难访问密钥库。密钥库密码可以设置为环境变量,而且应定期更改此密码,以限制攻击者可以尝试获取密钥库的时间段。

One important thing you should be aware of is that leaking this password does not necessarily mean the actual secrets stored in the keystore will also be leaked since an unauthorized person will also need to access the actual keystore file. Restricting access to the keystore file to a limited number of roles and having Quarkus processes running in one of these roles will make it harder for anyone outside the group access the keystore. The keystore password can be set as an environment variable and this password should be periodically changed to limit a window during which an attacker can try to get to the keystore.