此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Vault 3.1.2spring-doc.cn

支持 Vault 的 Secret 引擎

Spring Vault 附带了几个扩展来支持 Vault 的各种秘密引擎。spring-doc.cn

具体来说, Spring Vault 附带了以下扩展:spring-doc.cn

你可以通过直接 (, ) 上的方法使用所有其他后端。VaultTemplateVaultTemplate.read(…)VaultTemplate.write(…)spring-doc.cn

键值版本 1(“unversioned secrets”)

Secrets 引擎用于将任意 Secret 存储在为 Vault 配置的物理存储中。kvspring-doc.cn

以非版本控制方式运行密钥引擎时,仅保留键的最近写入的值。 非版本控制 kv 的好处是减少了每个键的存储大小,因为没有存储额外的元数据或历史记录。 此外,发送到以这种方式配置的后端的请求性能更高,因为存储调用更少,并且任何给定请求都没有锁定。kvspring-doc.cn

Spring Vault 附带了一个专用的键值 API 来封装各个键值 API 实现之间的差异。VaultKeyValueOperations 遵循 Vault CLI 设计。 这是 Vault 的主要命令行工具,提供 等命令。vault kv getvault kv putspring-doc.cn

通过指定版本和挂载路径,您可以将此 API 与两个 Key-Value 引擎版本一起使用。 以下示例使用 Key-Value 版本 1:spring-doc.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultKeyValueOperations keyValueOperations = operations.opsForKeyValue("secret",
							VaultKeyValueOperationsSupport.KeyValueBackend.KV_1);

keyValueOperations.put("elvis", Collections.singletonMap("password", "409-52-2002"));

VaultResponse read = keyValueOperations.get("elvis");
read.getRequiredData().get("social-security-number");

VaultKeyValueOperations 支持所有 Key-Value 操作,例如 、 、 、 。putgetdeletelistspring-doc.cn

或者,可以通过 VaultTemplate 使用 API,因为它的直接映射和简单使用,因为键和响应直接映射到输入和输出键。 以下示例说明了在 中写入和读取密钥。 Secrets 引擎挂载在 :mykeykvsecretspring-doc.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());

operations.write("secret/elvis", Collections.singletonMap("social-security-number", "409-52-2002"));

VaultResponse read = operations.read("secret/elvis");
read.getRequiredData().get("social-security-number");

您可以在 Vault 参考文档中找到有关 Vault 键值版本 1 API 的更多详细信息。spring-doc.cn

键值版本 2(“版本控制密钥”)

您可以在以下两个版本之一中运行密钥引擎。 本节介绍如何使用版本 2。运行后端的版本 2 时,密钥可以保留可配置数量的版本。 您可以检索旧版本的元数据和数据。 此外,您还可以使用 check-and-set 操作来避免无意中覆盖数据。kvkvspring-doc.cn

键值版本 1(“未版本控制的秘密”)类似,Spring Vault 附带了一个专用的键值 API 来封装各个键值 API 实现之间的差异。 Spring Vault 附带了一个专用的键值 API 来封装各个键值 API 实现之间的差异。 遵循 Vault CLI 设计。 这是 Vault 的主要命令行工具,提供 、 等命令。VaultKeyValueOperationsvault kv getvault kv putspring-doc.cn

通过指定版本和挂载路径,您可以将此 API 与两个 Key-Value 引擎版本一起使用。 以下示例使用 Key-Value 版本 2:spring-doc.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultKeyValueOperations keyValueOperations = operations.opsForKeyValue("secret",
							VaultKeyValueOperationsSupport.KeyValueBackend.KV_2);

keyValueOperations.put("elvis", Collections.singletonMap("social-security-number", "409-52-2002"));

VaultResponse read = keyValueOperations.get("elvis");
read.getRequiredData().get("social-security-number");

VaultKeyValueOperations 支持所有 Key-Value 操作,例如 、 、 、 。putgetdeletelistspring-doc.cn

您还可以与版本控制的键值 API 的具体内容进行交互。如果要获取特定密钥或需要访问元数据,这将非常有用。spring-doc.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultVersionedKeyValueOperations versionedOperations = operations.opsForVersionedKeyValue("secret");

Versioned.Metadata metadata = versionedOperations.put("elvis",							(1)
					Collections.singletonMap("social-security-number", "409-52-2002"));

Version version = metadata.getVersion();												(2)

Versioned<Object> ssn = versionedOperations.get("elvis", Version.from(42));				(3)

Versioned<SocialSecurityNumber> mappedSsn = versionedOperations.get("elvis",			(4)
											Version.from(42), SocialSecurityNumber.class);

Versioned<Map<String,String>> versioned = Versioned.create(Collections					(5)
						.singletonMap("social-security-number", "409-52-2002"),
						Version.from(42));

versionedOperations.put("elvis", version);
1 将机密存储在 中,在挂载下可用。elvissecret/
2 将数据存储在版本控制后端会返回版本号等元数据。
3 版本控制的键值 API 允许检索由版本号标识的特定版本。
4 版本控制的键值密钥可以映射到值对象中。
5 使用 CAS 更新版本控制密钥时,输入必须引用之前获取的版本。

虽然可以使用 v2 Secrets Engine through。 这不是最方便的方法,因为 API 为上下文路径以及 input/output 的表示方式提供了一种不同的方法。 具体来说,与实际 secret 的交互需要包装和解包数据部分,并在挂载和 secrets 键之间引入路径段。kvVaultTemplatedata/spring-doc.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());

operations.write("secret/data/elvis", Collections.singletonMap("data",
			Collections.singletonMap("social-security-number", "409-52-2002")));

VaultResponse read = operations.read("secret/data/ykey");
Map<String,String> data = (Map<String, String>) read.getRequiredData().get("data");
data.get("social-security-number");

您可以在 Vault 参考文档中找到有关 Vault 键值版本 2 API 的更多详细信息。spring-doc.cn

PKI(公钥基础设施)

Secrets 引擎通过实施证书颁发机构操作来表示证书的后端。pkispring-doc.cn

PKI 密钥引擎生成动态 X.509 证书。 借助此密钥引擎,服务可以获取证书,而无需经历通常的手动过程,例如生成私钥和 CSR、提交到 CA 并等待验证和签名过程完成。 Vault 的内置身份验证和授权机制提供了验证功能。spring-doc.cn

Spring Vault 支持通过 . 所有其他 PKI 功能都可以通过 使用。VaultPkiOperationsVaultOperationsspring-doc.cn

以下示例简要说明了如何颁发和吊销证书的用法:spring-doc.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultPkiOperations pkiOperations = operations.opsForPki("pki");

VaultCertificateRequest request = VaultCertificateRequest.builder()								(1)
			.ttl(Duration.ofHours(48))
			.altNames(Arrays.asList("prod.dc-1.example.com", "prod.dc-2.example.com"))
			.withIpSubjectAltName("1.2.3.4")
			.commonName("hello.example.com")
			.build();

VaultCertificateResponse response = pkiOperations.issueCertificate("production", request); 		(2)
CertificateBundle certificateBundle = response.getRequiredData();

KeyStore keyStore = certificateBundle.createKeyStore("my-keystore");							(3)

KeySpec privateKey = certificateBundle.getPrivateKeySpec();										(4)
X509Certificate certificate = certificateBundle.getX509Certificate();
X509Certificate caCertificate = certificateBundle.getX509IssuerCertificate();

pkiOperations.revoke(certificateBundle.getSerialNumber());										(5)
1 使用 VaultCertificateRequest 生成器构造证书请求。
2 从 Vault 请求证书。 Vault 充当证书颁发机构,并使用签名的 X.509 证书进行响应。 实际响应是 CertificateBundle
3 您可以直接以 Java KeyStore 的形式获取生成的证书,其中包含公钥和私钥以及颁发者证书。KeyStore 具有广泛的用途,这使得这种格式适合配置(例如,HTTP 客户端、数据库驱动程序或 SSL 保护的 HTTP 服务器)。
4 CertificateBundle 允许直接通过 Java 加密扩展 API 访问私钥以及公共证书和颁发者证书。
5 一旦证书不再使用(或已泄露),您可以通过其序列号吊销该证书。 Vault 在其 CRL 中包含已吊销的证书。

您可以在 Vault 参考文档中找到有关 Vault PKI 密钥 API 的更多详细信息。spring-doc.cn

Token 鉴权后端

此后端是不与实际密钥交互的身份验证后端。 相反,它提供对访问令牌管理的访问权限。 您可以在 Authentication methods 一章中阅读有关基于 Token 的身份验证的更多信息。spring-doc.cn

身份验证方法是内置的,可在 中自动使用。 它允许用户使用令牌进行身份验证,以及创建新令牌、按令牌撤销密钥等。token/auth/tokenspring-doc.cn

当任何其他身份验证方法返回身份时,Vault 核心会调用 token 方法为该身份创建新的唯一令牌。spring-doc.cn

您还可以使用令牌存储来绕过任何其他身份验证方法。您可以直接创建 Token,也可以对 Token 执行各种其他操作,例如续订和撤销。spring-doc.cn

Spring Vault 使用此后端来更新和撤销由配置的身份验证方法提供的会话令牌。spring-doc.cn

以下示例展示了如何从应用程序中请求、续订和撤销 Vault 令牌:spring-doc.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultTokenOperations tokenOperations = operations.opsForToken();

VaultTokenResponse tokenResponse = tokenOperations.create();                          (1)
VaultToken justAToken = tokenResponse.getToken();

VaultTokenRequest tokenRequest = VaultTokenRequest.builder().withPolicy("policy-for-myapp")
									.displayName("Access tokens for myapp")
									.renewable()
									.ttl(Duration.ofHours(1))
									.build();

VaultTokenResponse appTokenResponse = tokenOperations.create(tokenRequest);          (2)
VaultToken appToken = appTokenResponse.getToken();

tokenOperations.renew(appToken);                                                     (3)

tokenOperations.revoke(appToken);                                                    (4)
1 通过应用角色默认值创建令牌。
2 使用生成器 API,您可以为要请求的令牌定义精细设置。 请求令牌会返回一个 ,该令牌用作 Vault 令牌的值对象。VaultToken
3 您可以通过 Token API 续订 Token。通常,这是为了跟踪 Vault 会话令牌来完成的。SessionManager
4 如果需要,可以通过令牌 API 撤销令牌。通常,这是为了跟踪 Vault 会话令牌来完成的。SessionManager

您可以在 Vault 参考文档中找到有关 Vault Token Auth Method API 的更多详细信息。spring-doc.cn

Transit 后端

传输密钥引擎处理传输中数据的加密功能。 Vault 不存储发送到此 Secrets 引擎的数据。 它也可以看作是 “cryptography as a service” 或 “encryption as a service”。 传输密钥引擎还可以对数据进行签名和验证,生成数据的哈希和 HMAC,并充当随机字节源。spring-doc.cn

传输的主要用例是加密来自应用程序的数据,同时仍将加密数据存储在某些主数据存储中。 这减轻了应用程序开发人员进行适当加密和解密的负担,并将负担推给了 Vault 的运营商。spring-doc.cn

Spring Vault 支持广泛的 Transit 操作:spring-doc.cn

其中的所有操作都以键为中心。 Transit 引擎支持密钥和各种密钥类型的版本控制。 请注意,密钥类型可能会对可以使用的操作施加限制。transitspring-doc.cn

以下示例说明如何创建密钥以及如何加密和解密数据:spring-doc.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultTransitOperations transitOperations = operations.opsForTransit("transit");

transitOperations.createKey("my-aes-key", VaultTransitKeyCreationRequest.ofKeyType("aes128-gcm96"));	(1)

String ciphertext = transitOperations.encrypt("my-aes-key", "plaintext to encrypt");					(2)

String plaintext = transitOperations.decrypt("my-aes-key", ciphertext);									(3)
1 首先,我们需要一把钥匙。 每个键都需要指定类型。 支持加密、解密、密钥派生和收敛加密,其中我们本例需要加密和解密。aes128-gcm96
2 接下来,我们加密包含应加密的纯文本的 a。 input 使用 default 将字符串编码为其二进制表示形式。 请求令牌会返回一个 ,该令牌用作 Vault 令牌的值对象。 该方法返回 Base64 编码的密文,通常以 .StringStringCharsetVaultTokenencryptvault:
3 要将密文解密为纯文本,请调用该方法。 它解密密文并返回使用默认字符集解码的 a。decryptString

前面的示例使用简单字符串进行加密操作。 虽然这是一种简单的方法,但它存在 charset 错误配置的风险,并且不是二进制安全的。 当纯文本对数据(如图像、压缩数据或二进制数据结构)使用二进制表示时,需要二进制安全性。spring-doc.cn

要加密和解密二进制数据,请使用可以保存二进制值的 PlaintextCiphertext 值对象:spring-doc.cn

byte [] plaintext = "plaintext to encrypt".getBytes();

Ciphertext ciphertext = transitOperations.encrypt("my-aes-key", Plaintext.of(plaintext));			(1)

Plaintext decrypttedPlaintext = transitOperations.decrypt("my-aes-key", ciphertext);				(2)
1 假设密钥已经存在,我们将加密 Plaintext 对象。 作为回报,该方法返回一个 Ciphertext 对象。my-aes-keyencrypt
2 Ciphertext 对象可以直接用于解密,并返回 Plaintext 对象。

PlaintextCiphertext 附带一个上下文对象 VaultTransitContext。 它用于为收敛加密提供 nonce 值,以及用于利用密钥派生的上下文值。spring-doc.cn

Transit 允许对纯文本进行签名并验证给定纯文本的签名。 签名操作需要非对称密钥,通常使用椭圆曲线加密或 RSA。spring-doc.cn

签名使用公钥/私钥拆分来确保真实性。
签名者使用其私有密钥创建签名。否则,任何人都可以以您的名义签署消息。 验证者使用公钥部分来验证签名。实际签名通常是一个哈希值。

在内部,使用私钥计算和加密哈希以创建最终签名。验证会解密签名消息,计算他们自己的纯文本哈希值,并比较两个哈希值以检查签名是否有效。
byte [] plaintext = "plaintext to sign".getBytes();

transitOperations.createKey("my-ed25519-key", VaultTransitKeyCreationRequest.ofKeyType("ed25519"));	(1)

Signature signature = transitOperations.sign("my-ed25519-key", Plaintext.of(plaintext));			(2)

boolean valid = transitOperations.verify("my-ed25519-key", Plaintext.of(plaintext), signature);		(3)
1 签名需要非对称密钥。您可以使用任何 Elliptic Curve Cryptography 或 RSA 密钥类型。创建密钥后,您就具备了创建签名的所有先决条件。
2 将为纯文本消息创建签名。返回的 Signature 包含一个使用 Base64 字符的 ASCII 安全字符串。
3 要验证签名,验证需要一个 Signature 对象和纯文本消息。作为返回值,您可以获得签名是否有效。

您可以在 Vault 参考文档中找到有关 Vault Transit Backend 的更多详细信息。spring-doc.cn