Supporting for Vault’s Secret Engines
Spring Vault 附带了多个扩展以支持 Vault 的各种秘密引擎。 具体来说,Spring Vault 附带了以下扩展:
-
Transform (Enterprise Feature)
-
System Backend
您可以直接通过 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 get
、vault kv put
等命令。
你可以通过指定版本和装载路径使用这两个键值引擎版本。以下示例使用键值版本 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
。
另外,由于其直接映射和简单用法,API 还可以通过 VaultTemplate
使用,因为键和响应直接映射到输入和输出键。以下示例演示在 mykey
编写和读取一个密码。kv
密码引擎装载在 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 的更多详细信息。
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 get
、vault kv put
等命令。
你可以通过指定版本和装载路径使用这两个键值引擎版本。以下示例使用键值版本 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
。
你还可以与版本化键值 API 的具体细节进行交互。如果你想要获取一个特定密码,或者你需要访问元数据,这很有用。
/*
* 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 | 将秘密存储在`elvis`下,可通过 `secret/`挂载访问该存储。 |
2 | 将数据存储在版本化后端中,将返回版本号等元数据。 |
3 | 版本化的键值 API 允许按版本号检索特定版本。 |
4 | 版本化键值秘密可以映射到值对象中。 |
5 | 在使用 CAS 更新版本化秘密时,输入必须引用以前获得的版本。 |
虽然可以通过 VaultTemplate
使用 kv
v2 密码引擎。这不是最方便的方法,因为 API 为上下文路径和输入/输出表示方式提供了一个不同的方法。具体来说,与实际秘密的交互需要对数据部分进行包装和解包,并在装载和秘密键之间引入一个 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 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 的更多详细信息。
PKI (Public Key Infrastructure)
pki
密码引擎通过实现证书颁发机构操作来表示证书的后台。
PKI 密码引擎生成动态 X.509 证书。使用此密码引擎,服务无需经过生成私钥和 CSR、提交给 CA 以及等待验证和签名过程完成的通常手动过程即可获得证书。Vault 的内置身份验证和授权机制提供验证功能。
Spring Vault 支持通过 VaultPkiOperations
颁发、签名、撤销证书和检索 CRL。所有其他 PKI 功能都可以通过 VaultOperations
使用。
以下示例简要说明了如何颁发和撤销证书:
/*
* 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 | 使用 `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 令牌:
/*
* 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 | 通过应用角色默认值创建令牌。 |
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} 的版本控制。请注意,密钥类型可能对可以使用哪些操作施加限制。
以下示例展示了如何创建密钥以及如何加密和解密数据:
/*
* 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 | 首先,我们需要一个密钥。每个密钥都需要指定类型。aes128-gcm96 支持加密、解密、密钥派生和融合加密,其中我们需要加密和解密。 |
2 | 接下来,我们加密 String ,它包含应加密的纯文本。输入 String 使用默认 Charset 将字符串编码为其二进制表示。请求令牌会返回 VaultToken ,其用作 Vault 令牌的值对象。encrypt 方法返回 Base64 编码的密文,通常以 vault: 开头。 |
3 | 要将密文解密为纯文本,请调用 decrypt 方法。它解密密文并返回使用默认字符集解码的 String 。 |
上述示例使用简单字符串进行加密操作。虽然这种方法很简单,但它有字符集错误配置的风险,并且对于二进制文件不安全。当纯文本使用二进制表示来表示诸如图像、压缩数据或二进制数据结构等数据时,需要二进制安全性。
要加密和解密二进制数据,请使用可以保存二进制值 Plaintext
和 Ciphertext
值对象:
/*
* 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 | 假设密钥 my-aes-key 已准备就绪,我们正在加密 Plaintext 对象。作为回报,encrypt 方法返回 Ciphertext 对象。 |
2 | Ciphertext 对象可以直接用于解密,并返回 Plaintext 对象。 |
@ {s17} 和@ {s18} 附带一个上下文对象@ {s19}。它用于为@ {s20} 提供一个随机值,并提供一个上下文值以利用密钥派生。
传输允许对纯文本进行签名并验证给定纯文本的签名。签名操作需要不对称密钥,通常使用椭圆曲线密码术或 RSA。
签名使用公钥/私钥分割来确保真实性。签名者使用其私钥创建签名。否则,任何人都会以你的名义签署消息。验证者使用公钥部分验证签名。实际签名通常是一个哈希值。在内部,使用私钥计算和加密散列以创建最终签名。验证解密签名消息,为明文计算它们自己的散列,然后比较两个散列值以检查签名是否有效。 |
/*
* 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 | 签名需要非对称密钥。您可以使用任何椭圆曲线加密或 RSA 密钥类型。创建密钥后,您便具备创建签名的所有必要条件。 |
2 | 签名是针对纯文本消息创建的。返回的 Signature 包含使用 Base64 字符的 ASCII 安全字符串。 |
3 | 要验证签名,此验证需要一个签名对象和纯文本消息。作为返回值,您将获得签名是否有效。 |
您 可以在 Vault 参考文档中找到有关@ {s21} 的更多详细信息。