Supporting for Vault’s Secret Engines
Spring Vault 附带了多个扩展以支持 Vault 的各种秘密引擎。
Spring Vault ships with several extensions to support Vault’s various secret engines.
具体来说,Spring Vault 附带了以下扩展:
Specifically, Spring Vault ships with extensions for:
-
Transform (Enterprise Feature)
-
System Backend
您可以直接通过 VaultTemplate
上的方法(VaultTemplate.read(…)
、VaultTemplate.write(…)
)使用所有其他后端。
You can use all other backends through methods on VaultTemplate
directly (VaultTemplate.read(…)
, VaultTemplate.write(…)
).
Key-Value Version 1 ("unversioned secrets")
kv
秘密引擎用于在 Vault 的已配置物理存储中存储任意秘密。
The kv
secrets engine is used to store arbitrary secrets within the configured physical storage for Vault.
以非版本化方式运行 kv
秘密引擎时,只会保留最近写入的键值。非版本化 kv 的好处是每个键的存储空间减小,因为不再存储额外元数据或历史记录。此外,以这种方式配置的后端所接收的请求的性能会更高,因为存储调用的次数更少,并且对任何给定请求都没有锁定。
When running the kv
secrets engine in a non-versioned way, only the most recently written value for a key is preserved.
The benefits of non-versioned kv is a reduced storage size for each key, since no additional metadata or history is stored.
Additionally, requests going to a backend configured this way are more performant because there are fewer storage calls and no locking for any given request.
Spring Vault 附带一个专门的键值 API,以封装单个键值 API 实现之间的差异。VaultKeyValueOperations
遵循 Vault CLI 设计。这是 Vault 的主要命令行工具,提供诸如 vault kv get
、vault kv put
等命令。
Spring Vault ships with a dedicated Key-Value API to encapsulate differences between the individual Key-Value API implementations.
VaultKeyValueOperations
follows the Vault CLI design.
That’s the primary command line tool for Vault providing commands such as vault kv get
, vault kv put
and so on.
你可以通过指定版本和装载路径使用这两个键值引擎版本。以下示例使用键值版本 1:
You can use this API with both Key-Value engine versions by specifying the version and mount path. The following example uses the Key-Value version 1:
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.vault.documentation;
import java.util.Collections;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultKeyValueOperations;
import org.springframework.vault.core.VaultKeyValueOperationsSupport;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.support.VaultResponse;
/**
* @author Mark Paluch
*/
//@formatter:off
public class KeyValueV1 {
void vaultOperations() {
// tag::vaultOperations[]
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");
// end::vaultOperations[]
}
void keyValueApi() {
// tag::keyValueApi[]
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");
// end::keyValueApi[]
}
}
VaultKeyValueOperations
支持所有键值操作,例如 put
、get
、delete
、list
。
VaultKeyValueOperations
supports all Key-Value operations such as put
, get
, delete
, list
.
另外,由于其直接映射和简单用法,API 还可以通过 VaultTemplate
使用,因为键和响应直接映射到输入和输出键。以下示例演示在 mykey
编写和读取一个密码。kv
密码引擎装载在 secret
:
Alternatively, the API can be used through VaultTemplate
because of its direct mapping and simple use, as keys and responses map directly to input and output keys.
The following example illustrates writing and reading a secret at mykey
.
The kv
secrets engine is mounted at secret
:
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.vault.documentation;
import java.util.Collections;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultKeyValueOperations;
import org.springframework.vault.core.VaultKeyValueOperationsSupport;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.support.VaultResponse;
/**
* @author Mark Paluch
*/
//@formatter:off
public class KeyValueV1 {
void vaultOperations() {
// tag::vaultOperations[]
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");
// end::vaultOperations[]
}
void keyValueApi() {
// tag::keyValueApi[]
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");
// end::keyValueApi[]
}
}
您可以在 Vault 参考文档中找到有关 Vault Key-Value version 1 API 的更多详细信息。
You can find more details about the Vault Key-Value version 1 API in the Vault reference documentation.
Key-Value Version 2 ("versioned secrets")
你可以在两个版本中运行一个 kv
密码引擎。本节说明如何使用版本 2。在运行 kv
后端的版本 2 时,一个键可以保留一个可配置数量的版本。你可以检索较旧版本元数据和数据。此外,你可以使用检查和设置操作来避免意外地覆盖数据。
You can run the kv
secrets engine in one of two versions.
This section explains using version 2. When running version 2 of the kv
backend a key can retain a configurable number of versions.
You can retrieve the metadata and data of the older versions.
Additionally, you can use check-and-set operations to avoid unintentionally overwriting data.
类似于 Key-Value Version 1 ("unversioned secrets"),Spring Vault 附带一个专门的键值 API,以封装单个键值 API 实现之间的差异。Spring Vault 附带一个专门的键值 API,以封装单个键值 API 实现之间的差异。VaultKeyValueOperations
遵循 Vault CLI 设计。这是 Vault 的主要命令行工具,提供诸如 vault kv get
、vault kv put
等命令。
Similar to Key-Value Version 1 ("unversioned secrets"), Spring Vault ships with a dedicated Key-Value API to encapsulate differences between the individual Key-Value API implementations.
Spring Vault ships with a dedicated Key-Value API to encapsulate differences between the individual Key-Value API implementations.
VaultKeyValueOperations
follows the Vault CLI design.
That is the primary command line tool for Vault, providing commands such as vault kv get
, vault kv put
, and so on.
你可以通过指定版本和装载路径使用这两个键值引擎版本。以下示例使用键值版本 2:
You can use this API with both Key-Value engine versions by specifying the version and mount path. The following example uses Key-Value version 2:
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.vault.documentation;
import java.util.Collections;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultKeyValueOperations;
import org.springframework.vault.core.VaultKeyValueOperationsSupport;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.core.VaultVersionedKeyValueOperations;
import org.springframework.vault.support.VaultResponse;
import org.springframework.vault.support.Versioned;
import org.springframework.vault.support.Versioned.Version;
/**
* @author Mark Paluch
*/
//@formatter:off
public class KeyValueV2 {
void vaultOperations() {
// tag::vaultOperations[]
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");
// end::vaultOperations[]
}
void keyValueApi() {
// tag::keyValueApi[]
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");
// end::keyValueApi[]
}
void versionedApi() {
// tag::versionedApi[]
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);
// end::versionedApi[]
}
static class SocialSecurityNumber{
@JsonProperty("social-security-number")
String ssn;
}
}
VaultKeyValueOperations
支持所有键值操作,例如 put
、get
、delete
、list
。
VaultKeyValueOperations
supports all Key-Value operations, such as put
, get
, delete
, list
.
你还可以与版本化键值 API 的具体细节进行交互。如果你想要获取一个特定密码,或者你需要访问元数据,这很有用。
You can also interact with the specifics of the versioned key-value API. This is useful if you want to obtain a specific secret or you need access to the metadata.
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.vault.documentation;
import java.util.Collections;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultKeyValueOperations;
import org.springframework.vault.core.VaultKeyValueOperationsSupport;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.core.VaultVersionedKeyValueOperations;
import org.springframework.vault.support.VaultResponse;
import org.springframework.vault.support.Versioned;
import org.springframework.vault.support.Versioned.Version;
/**
* @author Mark Paluch
*/
//@formatter:off
public class KeyValueV2 {
void vaultOperations() {
// tag::vaultOperations[]
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");
// end::vaultOperations[]
}
void keyValueApi() {
// tag::keyValueApi[]
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");
// end::keyValueApi[]
}
void versionedApi() {
// tag::versionedApi[]
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);
// end::versionedApi[]
}
static class SocialSecurityNumber{
@JsonProperty("social-security-number")
String ssn;
}
}
1 | Store secrets at elvis in that is available under the secret/ mount. |
2 | Storing data in the versioned backend returns metadata such as the version number. |
3 | The versioned Key-Value API allows retrieval of specific versions identified by the version number. |
4 | Versioned key-value secrets can be mapped into value objects. |
5 | When updating versioned secrets using CAS, the input must refer to the previously obtained version. |
虽然可以通过 VaultTemplate
使用 kv
v2 密码引擎。这不是最方便的方法,因为 API 为上下文路径和输入/输出表示方式提供了一个不同的方法。具体来说,与实际秘密的交互需要对数据部分进行包装和解包,并在装载和秘密键之间引入一个 data/
路径段。
While using the kv
v2 secrets engine through VaultTemplate
is possible.
It is not the most convenient approach since the API offers a different approach to context paths and how input/output is represented.
Specifically, interaction with the actual secrets requires wrapping and unwrapping of the data section and introducing a data/
path segment between the mount and the secrets key.
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.vault.documentation;
import java.util.Collections;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultKeyValueOperations;
import org.springframework.vault.core.VaultKeyValueOperationsSupport;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.core.VaultVersionedKeyValueOperations;
import org.springframework.vault.support.VaultResponse;
import org.springframework.vault.support.Versioned;
import org.springframework.vault.support.Versioned.Version;
/**
* @author Mark Paluch
*/
//@formatter:off
public class KeyValueV2 {
void vaultOperations() {
// tag::vaultOperations[]
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");
// end::vaultOperations[]
}
void keyValueApi() {
// tag::keyValueApi[]
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");
// end::keyValueApi[]
}
void versionedApi() {
// tag::versionedApi[]
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);
// end::versionedApi[]
}
static class SocialSecurityNumber{
@JsonProperty("social-security-number")
String ssn;
}
}
您可以在 Vault 参考文档中找到有关 Vault Key-Value version 2 API 的更多详细信息。
You can find more details about the Vault Key-Value version 2 API in the Vault reference documentation.
PKI (Public Key Infrastructure)
pki
密码引擎通过实现证书颁发机构操作来表示证书的后台。
The pki
secrets engine represents a backend for certificates by implementing certificate authority operations.
PKI 密码引擎生成动态 X.509 证书。使用此密码引擎,服务无需经过生成私钥和 CSR、提交给 CA 以及等待验证和签名过程完成的通常手动过程即可获得证书。Vault 的内置身份验证和授权机制提供验证功能。
The PKI secrets engine generates dynamic X.509 certificates. With this secrets engine, services can get certificates without going through the usual manual process of generating a private key and CSR, submitting to a CA, and waiting for a verification and signing process to complete. Vault’s built-in authentication and authorization mechanisms provide the verification functionality.
Spring Vault 支持通过 VaultPkiOperations
颁发、签名、撤销证书和检索 CRL。所有其他 PKI 功能都可以通过 VaultOperations
使用。
Spring Vault supports issuing, signing, revoking certificates, and CRL retrieval through VaultPkiOperations
.
All other PKI functionality can be used through VaultOperations
.
以下示例简要说明了如何颁发和撤销证书:
The following examples explain briefly the use of how to issue and revoke certificates:
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.vault.documentation;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.security.spec.KeySpec;
import java.time.Duration;
import java.util.Arrays;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.core.VaultPkiOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.support.CertificateBundle;
import org.springframework.vault.support.VaultCertificateRequest;
import org.springframework.vault.support.VaultCertificateResponse;
/**
* @author Mark Paluch
*/
//@formatter:off
public class PKI {
void pkiApi() {
// tag::pkiApi[]
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)
// end::pkiApi[]
}
}
1 | Construct a certificate request by using the VaultCertificateRequest builder. |
2 | Request a certificate from Vault.
Vault acts as certificate authority and responds with a signed X.509 certificate.
The actual response is a CertificateBundle . |
3 | You can obtain generated certificates directly as Java KeyStore that contains public and private keys as well as the issuer certificate. KeyStore has a wide range of uses, which makes this format suitable to configure (for example a HTTP client, a database driver, or an SSL-secured HTTP server). |
4 | CertificateBundle allows accessing the private key and the public and issuer certificates directly through the Java Cryptography Extension API. |
5 | Once a certificate is no longer in use (or it was compromised), you can revoke it through its serial number. Vault includes the revoked certificate in its CRL. |
您 可以在 Vault 参考文档中找到有关@ {s13} 的更多详细信息。
You can find more details about the Vault PKI secrets API in the Vault reference documentation.
Token Authentication Backend
此后台是一个不与实际秘密交互的身份验证后台。相反,它允许访问访问令牌管理。你可以在 authentication methods chapter 中阅读有关 Token-based authentication 的更多信息。
This backend is an authentication backend that does not interact with actual secrets. Rather, it gives access to access token management. You can read more about vault.authentication.token in the vault.core.authentication.
token
身份验证方法是内置的,并且在 /auth/token
中自动可用。它使用户能够使用令牌进行身份验证,以及创建新令牌、按令牌撤销秘密等。
The token
authentication method is built-in and automatically available at /auth/token
.
It lets users authenticate using a token, as well to create new tokens, revoke secrets by token, and more.
当任何其他身份验证方法返回身份时,Vault 核心会调用令牌方法为该身份创建一个新的唯一令牌。
When any other auth method returns an identity, Vault core invokes the token method to create a new unique token for that identity.
您还可以使用令牌存储来规避任何其他认证方法。您可以直接创建令牌,以及对令牌执行各种其他操作,例如续订和吊销。
You can also use the token store to bypass any other auth method. You can create tokens directly, as well as perform a variety of other operations on tokens, such as renewal and revocation.
Spring Vault 使用此后端续订和吊销由已配置的 authentication method 提供的会话令牌。
Spring Vault uses this backend to renew and revoke the session tokens supplied by the configured vault.core.authentication.
以下示例展示了如何从应用程序中请求、续订和吊销 Vault 令牌:
The following examples show how to request, renew and revoke a Vault token from within your application:
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.vault.documentation;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.security.spec.KeySpec;
import java.time.Duration;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.core.VaultTokenOperations;
import org.springframework.vault.support.CertificateBundle;
import org.springframework.vault.support.VaultCertificateResponse;
import org.springframework.vault.support.VaultToken;
import org.springframework.vault.support.VaultTokenRequest;
import org.springframework.vault.support.VaultTokenResponse;
/**
* @author Mark Paluch
*/
//@formatter:off
public class Token {
void tokenApi() {
// tag::tokenApi[]
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)
// end::tokenApi[]
}
}
1 | Create an token by applying role defaults. |
2 | Using the builder API, you can define fine-grained settings for the token to request.
Requesting a token returns a VaultToken , which is used as value object for Vault tokens. |
3 | You can renew tokens through the Token API. Typically, that is done by SessionManager to keep track of the Vault session token. |
4 | Tokens can be revoked if needed through the Token API. Typically, that is done by SessionManager to keep track of the Vault session token. |
您 可以在 Vault 参考文档中找到有关@ {s14} 的更多详细信息。
You can find more details about the Vault Token Auth Method API in the Vault reference documentation.
Transit Backend
传输机密引擎处理传输中数据的加密函数。Vault 不会存储发送到此机密引擎的数据。它也可以被视为“即服务密码术”或“即服务加密”。传输机密引擎还可以对数据进行签名和验证,生成数据哈希和 HMAC,并充当随机字节源。
The transit secrets engine handles cryptographic functions on data in-transit. Vault does not store the data sent to this secrets engine. It can also be seen as "cryptography as a service" or "encryption as a service". The transit secrets engine can also sign and verify data, generate hashes and HMACs of data, and act as a random bytes source.
传输的主要用例是从应用程序加密数据,同时仍将加密数据存储在某个主数据存储中。这解决了应用程序开发人员的正确加密和解密负担,并将负担转嫁到了 Vault 操作员身上。
The primary use case for transit is to encrypt data from applications while still storing that encrypted data in some primary data store. This relieves the burden of proper encryption and decryption from application developers and pushes the burden onto the operators of Vault.
Spring Vault 支持广泛的传输操作:
Spring Vault supports a wide range of Transit operations:
-
Key creation
-
Key reconfiguration
-
Encryption/Decryption/Rewrapping
-
HMAC computation
-
Signing and signature verification
@ {s15} 中的所有操作都围绕密钥展开。Transit 引擎支持密钥和@ {s16} 的版本控制。请注意,密钥类型可能对可以使用哪些操作施加限制。
All operations within transit
are centered around keys.
The Transit engine supports the versioning of keys and a variety of key types.
Note that the key type may impose a limitation on which operations can used.
以下示例展示了如何创建密钥以及如何加密和解密数据:
The following examples shows how to create a key and how to encrypt and decrypt data:
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.vault.documentation;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.core.VaultTransitOperations;
import org.springframework.vault.support.Ciphertext;
import org.springframework.vault.support.Plaintext;
import org.springframework.vault.support.Signature;
import org.springframework.vault.support.VaultTransitKeyCreationRequest;
/**
* @author Mark Paluch
*/
//@formatter:off
public class Transit {
void encryptSimple() {
// tag::encryptSimple[]
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)
// end::encryptSimple[]
}
void encryptPlaintext(VaultTransitOperations transitOperations) {
// tag::encryptPlaintext[]
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)
// end::encryptPlaintext[]
}
void signVerify(VaultTransitOperations transitOperations) {
// tag::signVerify[]
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)
// end::signVerify[]
}
}
1 | First, we need a key to begin with.
Each key requires the type to be specified. aes128-gcm96 supports encryption, decryption, key derivation, and convergent encryption, of which we need encryption and decryption for this example. |
2 | Next, we encrypt a String that contains the plain text that should be encrypted.
The input String uses the default Charset to encode the string into its binary representation.
Requesting a token returns a VaultToken , which is used as value object for Vault tokens.
The encrypt method returns Base64-encoded ciphertext, typically starting with vault: . |
3 | To decrypt ciphertext into plain text, call the decrypt method.
It decrypts the ciphertext and returns a String that is decoded using the default charset. |
上述示例使用简单字符串进行加密操作。虽然这种方法很简单,但它有字符集错误配置的风险,并且对于二进制文件不安全。当纯文本使用二进制表示来表示诸如图像、压缩数据或二进制数据结构等数据时,需要二进制安全性。
The preceeding example uses simple strings for cryptographic operations. While it is a simple approach, it bears the risk of charset misconfiguration and is not binary-safe. Binary safety is required when the plain text uses a binary representation for data such as images, compressed data, or binary data structures.
要加密和解密二进制数据,请使用可以保存二进制值 Plaintext
和 Ciphertext
值对象:
To encrypt and decrypt binary data, use the Plaintext
and Ciphertext
value objects that can hold binary values:
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.vault.documentation;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.core.VaultTransitOperations;
import org.springframework.vault.support.Ciphertext;
import org.springframework.vault.support.Plaintext;
import org.springframework.vault.support.Signature;
import org.springframework.vault.support.VaultTransitKeyCreationRequest;
/**
* @author Mark Paluch
*/
//@formatter:off
public class Transit {
void encryptSimple() {
// tag::encryptSimple[]
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)
// end::encryptSimple[]
}
void encryptPlaintext(VaultTransitOperations transitOperations) {
// tag::encryptPlaintext[]
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)
// end::encryptPlaintext[]
}
void signVerify(VaultTransitOperations transitOperations) {
// tag::signVerify[]
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)
// end::signVerify[]
}
}
1 | Assuming a key my-aes-key is already in place, we’re encrypting the Plaintext object.
In return, the encrypt method returns a Ciphertext object. |
2 | The Ciphertext object can be used directly for decryption and returns a Plaintext object. |
@ {s17} 和@ {s18} 附带一个上下文对象@ {s19}。它用于为@ {s20} 提供一个随机值,并提供一个上下文值以利用密钥派生。
Plaintext
and Ciphertext
come with a contextual object, VaultTransitContext
.
It is used to supply a nonce value for convergent encryption and for a context value to make use of key derivation.
传输允许对纯文本进行签名并验证给定纯文本的签名。签名操作需要不对称密钥,通常使用椭圆曲线密码术或 RSA。
Transit allows for signing plain text and verifying the signature for a given plain text. Sign operations require an asymmetric key, typically using Elliptic Curve Cryptography or RSA.
签名使用公钥/私钥分割来确保真实性。签名者使用其私钥创建签名。否则,任何人都会以你的名义签署消息。验证者使用公钥部分验证签名。实际签名通常是一个哈希值。在内部,使用私钥计算和加密散列以创建最终签名。验证解密签名消息,为明文计算它们自己的散列,然后比较两个散列值以检查签名是否有效。 |
Signatures use the public/private key split to ensure authenticity. The signer uses its private key to create a signature. Otherwise, anybody would be able to sign messages in your name. The verifier uses the public key part to verify the signature. The actual signature is typically a hash value. Internally, the hash gets computed and encrypted using the private key to create the final signature. The verification decrypts the signature message, computes their own hash for the plain text and compares both hash values to check whether the signature is valid or not. |
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.vault.documentation;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.core.VaultTransitOperations;
import org.springframework.vault.support.Ciphertext;
import org.springframework.vault.support.Plaintext;
import org.springframework.vault.support.Signature;
import org.springframework.vault.support.VaultTransitKeyCreationRequest;
/**
* @author Mark Paluch
*/
//@formatter:off
public class Transit {
void encryptSimple() {
// tag::encryptSimple[]
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)
// end::encryptSimple[]
}
void encryptPlaintext(VaultTransitOperations transitOperations) {
// tag::encryptPlaintext[]
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)
// end::encryptPlaintext[]
}
void signVerify(VaultTransitOperations transitOperations) {
// tag::signVerify[]
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)
// end::signVerify[]
}
}
1 | Signing requires an asymmetric key. You can use any Elliptic Curve Cryptography or RSA key type. Once the key is created, you have all the prerequisites in place to create a signature. |
2 | The signature gets created for a plain text message. The returned Signature contains an ASCII-safe string that uses Base64 characters. |
3 | To verify the signature, the verification requires a Signature object and the plain text message. As the return value, you get whether the signature was valid or not. |
您 可以在 Vault 参考文档中找到有关@ {s21} 的更多详细信息。
You can find more details about the Vault Transit Backend in the Vault reference documentation.