Supporting for Vault’s Secret Engines

Spring Vault 附带了多个扩展以支持 Vault 的各种秘密引擎。 具体来说,Spring Vault 附带了以下扩展:

您可以直接通过 VaultTemplate 上的方法(VaultTemplate.read(…)VaultTemplate.write(…))使用所有其他后端。

Key-Value Version 1 ("unversioned secrets")

kv 秘密引擎用于在 Vault 的已配置物理存储中存储任意秘密。

以非版本化方式运行 kv 秘密引擎时,只会保留最近写入的键值。非版本化 kv 的好处是每个键的存储空间减小,因为不再存储额外元数据或历史记录。此外,以这种方式配置的后端所接收的请求的性能会更高,因为存储调用的次数更少,并且对任何给定请求都没有锁定。

Spring Vault 附带一个专门的键值 API,以封装单个键值 API 实现之间的差异。VaultKeyValueOperations 遵循 Vault CLI 设计。这是 Vault 的主要命令行工具,提供诸如 vault kv getvault kv put 等命令。

你可以通过指定版本和装载路径使用这两个键值引擎版本。以下示例使用键值版本 1:

link:example$KeyValueV1.java[role=include]

VaultKeyValueOperations 支持所有键值操作,例如 putgetdeletelist

另外,由于其直接映射和简单用法,API 还可以通过 VaultTemplate 使用,因为键和响应直接映射到输入和输出键。以下示例演示在 mykey 编写和读取一个密码。kv 密码引擎装载在 secret

link:example$KeyValueV1.java[role=include]

您可以在 Vault 参考文档中找到有关 Vault Key-Value version 1 API 的更多详细信息。

Key-Value Version 2 ("versioned secrets")

你可以在两个版本中运行一个 kv 密码引擎。本节说明如何使用版本 2。在运行 kv 后端的版本 2 时,一个键可以保留一个可配置数量的版本。你可以检索较旧版本元数据和数据。此外,你可以使用检查和设置操作来避免意外地覆盖数据。

类似于 Key-Value Version 1 ("unversioned secrets"),Spring Vault 附带一个专门的键值 API,以封装单个键值 API 实现之间的差异。Spring Vault 附带一个专门的键值 API,以封装单个键值 API 实现之间的差异。VaultKeyValueOperations 遵循 Vault CLI 设计。这是 Vault 的主要命令行工具,提供诸如 vault kv getvault kv put 等命令。

你可以通过指定版本和装载路径使用这两个键值引擎版本。以下示例使用键值版本 2:

link:example$KeyValueV2.java[role=include]

VaultKeyValueOperations 支持所有键值操作,例如 putgetdeletelist

你还可以与版本化键值 API 的具体细节进行交互。如果你想要获取一个特定密码,或者你需要访问元数据,这很有用。

link:example$KeyValueV2.java[role=include]
1 将秘密存储在`elvis`下,可通过 `secret/`挂载访问该存储。
2 将数据存储在版本化后端中,将返回版本号等元数据。
3 版本化的键值 API 允许按版本号检索特定版本。
4 版本化键值秘密可以映射到值对象中。
5 在使用 CAS 更新版本化秘密时,输入必须引用以前获得的版本。

虽然可以通过 VaultTemplate 使用 kv v2 密码引擎。这不是最方便的方法,因为 API 为上下文路径和输入/输出表示方式提供了一个不同的方法。具体来说,与实际秘密的交互需要对数据部分进行包装和解包,并在装载和秘密键之间引入一个 data/ 路径段。

link:example$KeyValueV2.java[role=include]

您可以在 Vault 参考文档中找到有关 Vault Key-Value version 2 API 的更多详细信息。

PKI (Public Key Infrastructure)

pki 密码引擎通过实现证书颁发机构操作来表示证书的后台。

PKI 密码引擎生成动态 X.509 证书。使用此密码引擎,服务无需经过生成私钥和 CSR、提交给 CA 以及等待验证和签名过程完成的通常手动过程即可获得证书。Vault 的内置身份验证和授权机制提供验证功能。

Spring Vault 支持通过 VaultPkiOperations 颁发、签名、撤销证书和检索 CRL。所有其他 PKI 功能都可以通过 VaultOperations 使用。

以下示例简要说明了如何颁发和撤销证书:

link:example$PKI.java[role=include]
1 使用 `VaultCertificateRequest`构建器构造证书请求。
2 从 Vault 请求证书。Vault 充当证书颁发机构,并使用签名 X.509 证书进行响应。实际的响应是 CertificateBundle
3 你可以将生成的证书直接获取为 Java 密钥库,其中包含公钥和私钥以及颁发者证书。KeyStore 具有广泛的用途,这使得该格式适用于配置(例如,HTTP 客户端、数据库驱动程序或 SSL 安全的 HTTP 服务器)。
4 `CertificateBundle`允许直接通过 Java Cryptography Extension API 访问私钥以及公钥和颁发者证书。
5 一旦证书不再使用(或受到破坏),你可以通过其序列号撤销该证书。Vault 将撤销的证书包含在其 CRL 中。

可以在 Vault 参考文档中找到有关@ {s13} 的更多详细信息。

Token Authentication Backend

此后台是一个不与实际秘密交互的身份验证后台。相反,它允许访问访问令牌管理。你可以在 authentication methods chapter 中阅读有关 Token-based authentication 的更多信息。

token 身份验证方法是内置的,并且在 /auth/token 中自动可用。它使用户能够使用令牌进行身份验证,以及创建新令牌、按令牌撤销秘密等。

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

您还可以使用令牌存储来规避任何其他认证方法。您可以直接创建令牌,以及对令牌执行各种其他操作,例如续订和吊销。

Spring Vault 使用此后端续订和吊销由已配置的 authentication method 提供的会话令牌。

以下示例展示了如何从应用程序中请求、续订和吊销 Vault 令牌:

link:example$Token.java[role=include]
1 通过应用角色默认值创建令牌。
2 使用构建器 API,您可以为要请求的令牌定义细粒度的设置。请求令牌会返回 VaultToken,其用作 Vault 令牌的值对象。
3 您可以通过令牌 API 续订令牌。通常,这通过 SessionManager 来执行,以跟踪 Vault 会话令牌。
4 如果需要,可以通过令牌 API 撤销令牌。通常,这通过 SessionManager 来执行,以跟踪 Vault 会话令牌。

可以在 Vault 参考文档中找到有关@ {s14} 的更多详细信息。

Transit Backend

传输机密引擎处理传输中数据的加密函数。Vault 不会存储发送到此机密引擎的数据。它也可以被视为“即服务密码术”或“即服务加密”。传输机密引擎还可以对数据进行签名和验证,生成数据哈希和 HMAC,并充当随机字节源。

传输的主要用例是从应用程序加密数据,同时仍将加密数据存储在某个主数据存储中。这解决了应用程序开发人员的正确加密和解密负担,并将负担转嫁到了 Vault 操作员身上。

Spring Vault 支持广泛的传输操作:

  • Key creation

  • Key reconfiguration

  • Encryption/Decryption/Rewrapping

  • HMAC computation

  • Signing and signature verification

@ {s15} 中的所有操作都围绕密钥展开。Transit 引擎支持密钥和@ {s16} 的版本控制。请注意,密钥类型可能对可以使用哪些操作施加限制。

以下示例展示了如何创建密钥以及如何加密和解密数据:

link:example$Transit.java[role=include]
1 首先,我们需要一个密钥。每个密钥都需要指定类型。aes128-gcm96 支持加密、解密、密钥派生和融合加密,其中我们需要加密和解密。
2 接下来,我们加密 String,它包含应加密的纯文本。输入 String 使用默认 Charset 将字符串编码为其二进制表示。请求令牌会返回 VaultToken,其用作 Vault 令牌的值对象。encrypt 方法返回 Base64 编码的密文,通常以 vault: 开头。
3 要将密文解密为纯文本,请调用 decrypt 方法。它解密密文并返回使用默认字符集解码的 String

上述示例使用简单字符串进行加密操作。虽然这种方法很简单,但它有字符集错误配置的风险,并且对于二进制文件不安全。当纯文本使用二进制表示来表示诸如图像、压缩数据或二进制数据结构等数据时,需要二进制安全性。

要加密和解密二进制数据,请使用可以保存二进制值 PlaintextCiphertext 值对象:

link:example$Transit.java[role=include]
1 假设密钥 my-aes-key 已准备就绪,我们正在加密 Plaintext 对象。作为回报,encrypt 方法返回 Ciphertext 对象。
2 Ciphertext 对象可以直接用于解密,并返回 Plaintext 对象。

@ {s17}@ {s18} 附带一个上下文对象@ {s19}。它用于为@ {s20} 提供一个随机值,并提供一个上下文值以利用密钥派生。

传输允许对纯文本进行签名并验证给定纯文本的签名。签名操作需要不对称密钥,通常使用椭圆曲线密码术或 RSA。

签名使用公钥/私钥分割来确保真实性。签名者使用其私钥创建签名。否则,任何人都会以你的名义签署消息。验证者使用公钥部分验证签名。实际签名通常是一个哈希值。在内部,使用私钥计算和加密散列以创建最终签名。验证解密签名消息,为明文计算它们自己的散列,然后比较两个散列值以检查签名是否有效。

link:example$Transit.java[role=include]
1 签名需要非对称密钥。您可以使用任何椭圆曲线加密或 RSA 密钥类型。创建密钥后,您便具备创建签名的所有必要条件。
2 签名是针对纯文本消息创建的。返回的 Signature 包含使用 Base64 字符的 ASCII 安全字符串。
3 要验证签名,此验证需要一个签名对象和纯文本消息。作为返回值,您将获得签名是否有效。

可以在 Vault 参考文档中找到有关@ {s21} 的更多详细信息。