你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
适用于 Java 的 Azure 密钥保管库 密钥客户端库 - 版本 4.7.1
Azure 密钥保管库 是一种云服务,提供密钥的安全存储,用于加密数据。 多个密钥和同一密钥的多个版本可以保存在 Azure 密钥保管库中。 Azure 密钥保管库中的加密密钥表示为 JSON Web 密钥 [JWK] 对象。
Azure 密钥保管库托管 HSM 是一种完全托管、高度可用、单租户且符合标准的云服务,可用于使用 FIPS 140-2 级别 3 验证的 HSM 保护云应用程序的加密密钥。
Azure 密钥保管库密钥库客户端支持 RSA 密钥和椭圆曲线 (EC) 密钥,每个密钥在硬件安全模块 (HSM) 中都有相应的支持。 它提供创建、检索、更新、删除、清除、备份、还原以及列出密钥及其版本的操作。
入门
添加包
包括 BOM 文件
请将 包含在 azure-sdk-bom
项目中,以依赖于库的正式发布 (正式发布) 版本。 在以下代码段中,将 {bom_version_to_target} 占位符替换为版本号。 若要详细了解 BOM,请参阅 AZURE SDK BOM 自述文件。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-sdk-bom</artifactId>
<version>{bom_version_to_target}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后在 dependencies 节中包含直接依赖项,不带版本标记,如下所示。
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-keys</artifactId>
</dependency>
</dependencies>
包括直接依赖项
如果要依赖于 BOM 中不存在的特定版本的库,请将直接依赖项添加到项目中,如下所示。
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-keys</artifactId>
<version>4.7.1</version>
</dependency>
先决条件
- Java 开发工具包 (JDK) 8 或更高版本。
- 一个 Azure 订阅。
- 下列类型作之一:
- 现有的 Azure 密钥保管库。 如果需要创建密钥保管库,可以在 Azure 门户中按照 本文档中的步骤操作。 或者,可以按照 本文档中的步骤使用 Azure CLI。
- 现有的 Azure 密钥保管库 托管 HSM。 如果需要创建托管 HSM,可以使用 Azure CLI 执行 本文档中的步骤。
验证客户端
若要与 Azure 密钥保管库 服务交互,需要创建 类或 CryptographyClient
类的KeyClient
实例,以及保管库 URL 和凭据对象。 本文档中显示的示例使用名为 的 DefaultAzureCredential
凭据对象,该对象适用于大多数方案,包括本地开发和生产环境。 此外,我们建议使用 托管标识 在生产环境中进行身份验证。
可以在 Azure 标识文档中找到有关不同身份验证方式及其相应凭据类型的详细信息。
创建密钥客户端
执行 最适合你的身份验证设置 并将 your-key-vault-url 替换为密钥保管库或托管 HSM 的 URL 后,可以创建 KeyClient
:
KeyClient keyClient = new KeyClientBuilder()
.vaultUrl("<your-key-vault-url>")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
注意:对于使用异步客户端,请使用
KeyAsyncClient
而不是KeyClient
和 调用buildAsyncClient()
。
创建加密客户端
执行DefaultAzureCredential
最适合你的设置并将 your-key-vault-url 替换为密钥保管库或托管 HSM 的 URL 后,可以创建 CryptographyClient
:
// Create client with key identifier from Key Vault.
CryptographyClient cryptoClient = new CryptographyClientBuilder()
.keyIdentifier("<your-key-id-from-key-vault>")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
注意:对于使用异步客户端,请使用
CryptographyAsyncClient
而不是CryptographyClient
和 调用buildAsyncClient()
。
关键概念
密钥
Azure 密钥保管库支持多种密钥类型 (RSA
&EC
) 和算法,并且支持将硬件安全模块 (HSM) 用于高价值密钥。 除了密钥材料之外,还可以指定以下属性:
- enabled:指定密钥是否已启用并可用于加密操作。
- not_before:标识之前不得将密钥用于加密操作的时间。
- expires:标识在或之后不得将密钥用于加密操作的过期时间。
- created:指示创建此版本的密钥。
- updated:指示更新此版本的密钥的时间。
密钥客户端:
密钥客户端与 Azure 密钥保管库 服务执行交互,以获取、设置、更新、删除和列出密钥及其版本。 异步 (KeyAsyncClient
) 和同步 (KeyClient
) 客户端存在于 SDK 中,允许根据应用程序的用例选择客户端。 初始化密钥后,可以与密钥保管库中的主要资源类型进行交互。
加密客户端:
加密客户端在本地执行加密操作或调用 Azure 密钥保管库服务,具体取决于本地可用的密钥信息量。 它支持加密、解密、签名、验证、密钥包装、密钥解包和检索配置的密钥。 异步 (CryptographyAsyncClient
) 和同步 (CryptographyClient
) 客户端存在于 SDK 中,允许根据应用程序的用例选择客户端。
示例
同步 API
以下部分提供了几个代码片段,涵盖了一些最常见的 Azure 密钥保管库 密钥服务任务,包括:
创建密钥
创建要存储在 Azure 密钥保管库中的密钥。
createKey
在密钥保管库中创建新密钥。 如果已存在同名的密钥,则会创建该密钥的新版本。
KeyVaultKey rsaKey = keyClient.createRsaKey(new CreateRsaKeyOptions("CloudRsaKey")
.setExpiresOn(OffsetDateTime.now().plusYears(1))
.setKeySize(2048));
System.out.printf("Key created with name \"%s\" and id %s%n", rsaKey.getName(), rsaKey.getId());
KeyVaultKey ecKey = keyClient.createEcKey(new CreateEcKeyOptions("CloudEcKey")
.setCurveName(KeyCurveName.P_256)
.setExpiresOn(OffsetDateTime.now().plusYears(1)));
System.out.printf("Key created with name \"%s\" and id %s%n", ecKey.getName(), ecKey.getId());
检索密钥
通过调用 getKey
检索以前存储的密钥。
KeyVaultKey key = keyClient.getKey("<key-name>");
System.out.printf("A key was returned with name \"%s\" and id %s%n", key.getName(), key.getId());
更新现有密钥
通过调用 updateKeyProperties
更新现有密钥。
// Get the key to update.
KeyVaultKey key = keyClient.getKey("<key-name>");
// Update the expiry time of the key.
key.getProperties().setExpiresOn(OffsetDateTime.now().plusDays(30));
KeyVaultKey updatedKey = keyClient.updateKeyProperties(key.getProperties());
System.out.printf("Key's updated expiry time: %s%n", updatedKey.getProperties().getExpiresOn());
删除密钥
通过调用 beginDeleteKey
删除现有密钥。
SyncPoller<DeletedKey, Void> deletedKeyPoller = keyClient.beginDeleteKey("<key-name>");
PollResponse<DeletedKey> deletedKeyPollResponse = deletedKeyPoller.poll();
// Deleted key is accessible as soon as polling begins.
DeletedKey deletedKey = deletedKeyPollResponse.getValue();
// Deletion date only works for a soft-delete enabled key vault.
System.out.printf("Deletion date: %s%n", deletedKey.getDeletedOn());
// The key is being deleted on the server.
deletedKeyPoller.waitForCompletion();
列出密钥
通过调用 listPropertiesOfKeys
列出密钥保管库中的密钥。
// List operations don't return the keys with key material information. So, for each returned key we call getKey to
// get the key with its key material information.
for (KeyProperties keyProperties : keyClient.listPropertiesOfKeys()) {
KeyVaultKey keyWithMaterial = keyClient.getKey(keyProperties.getName(), keyProperties.getVersion());
System.out.printf("Received key with name \"%s\" and type \"%s\"%n", keyWithMaterial.getName(),
keyWithMaterial.getKey().getKeyType());
}
加密
通过调用 encrypt
加密纯文本。
byte[] plaintext = new byte[100];
new SecureRandom(SEED).nextBytes(plaintext);
// Let's encrypt a simple plain text of size 100 bytes.
EncryptResult encryptionResult = cryptoClient.encrypt(EncryptionAlgorithm.RSA_OAEP, plaintext);
System.out.printf("Returned ciphertext size is %d bytes with algorithm \"%s\"%n",
encryptionResult.getCipherText().length, encryptionResult.getAlgorithm());
解密
通过调用 decrypt
解密加密的内容。
byte[] plaintext = new byte[100];
new SecureRandom(SEED).nextBytes(plaintext);
EncryptResult encryptionResult = cryptoClient.encrypt(EncryptionAlgorithm.RSA_OAEP, plaintext);
//Let's decrypt the encrypted result.
DecryptResult decryptionResult = cryptoClient.decrypt(EncryptionAlgorithm.RSA_OAEP, encryptionResult.getCipherText());
System.out.printf("Returned plaintext size is %d bytes%n", decryptionResult.getPlainText().length);
异步 API
以下部分提供了几个代码片段,涵盖了一些最常见的异步 Azure 密钥保管库 密钥服务任务,包括:
注意:应在main类/线程中的函数调用后添加
System.in.read()
或Thread.sleep()
,以允许在main应用程序/线程退出之前执行和完成异步函数/操作。
异步创建密钥
创建要存储在 Azure 密钥保管库中的密钥。
createKey
在密钥保管库中创建新密钥。 如果已存在同名的密钥,则会创建该密钥的新版本。
keyAsyncClient.createRsaKey(new CreateRsaKeyOptions("CloudRsaKey")
.setExpiresOn(OffsetDateTime.now().plusYears(1))
.setKeySize(2048))
.subscribe(key ->
System.out.printf("Key created with name \"%s\" and id %s%n", key.getName(), key.getId()));
keyAsyncClient.createEcKey(new CreateEcKeyOptions("CloudEcKey")
.setExpiresOn(OffsetDateTime.now().plusYears(1)))
.subscribe(key ->
System.out.printf("Key created with name \"%s\" and id %s%n", key.getName(), key.getId()));
异步检索密钥
通过调用 getKey
检索以前存储的密钥。
keyAsyncClient.getKey("<key-name>")
.subscribe(key ->
System.out.printf("Key was returned with name \"%s\" and id %s%n", key.getName(), key.getId()));
异步更新现有密钥
通过调用 updateKeyProperties
更新现有密钥。
keyAsyncClient.getKey("<key-name>")
.flatMap(key -> {
// Update the expiry time of the key.
key.getProperties().setExpiresOn(OffsetDateTime.now().plusDays(50));
return keyAsyncClient.updateKeyProperties(key.getProperties());
}).subscribe(updatedKey ->
System.out.printf("Key's updated expiry time: %s%n", updatedKey.getProperties().getExpiresOn()));
异步删除密钥
通过调用 beginDeleteKey
删除现有密钥。
keyAsyncClient.beginDeleteKey("<key-name>")
.subscribe(pollResponse -> {
System.out.printf("Deletion status: %s%n", pollResponse.getStatus());
System.out.printf("Deleted key name: %s%n", pollResponse.getValue().getName());
System.out.printf("Key deletion date: %s%n", pollResponse.getValue().getDeletedOn());
});
异步列出密钥
通过调用 listPropertiesOfKeys
列出 Azure 密钥保管库中的密钥。
// The List Keys operation returns keys without their value, so for each key returned we call `getKey` to get its value
// as well.
keyAsyncClient.listPropertiesOfKeys()
.flatMap(keyProperties -> keyAsyncClient.getKey(keyProperties.getName(), keyProperties.getVersion()))
.subscribe(key ->
System.out.printf("Received key with name \"%s\" and type \"%s\"", key.getName(), key.getKeyType()));
异步加密
通过调用 encrypt
加密纯文本。
byte[] plaintext = new byte[100];
new SecureRandom(SEED).nextBytes(plaintext);
// Let's encrypt a simple plain text of size 100 bytes.
cryptoAsyncClient.encrypt(EncryptionAlgorithm.RSA_OAEP, plaintext)
.subscribe(encryptionResult -> System.out.printf("Returned ciphertext size is %d bytes with algorithm \"%s\"%n",
encryptionResult.getCipherText().length, encryptionResult.getAlgorithm()));
异步解密
通过调用 decrypt
解密加密的内容。
byte[] plaintext = new byte[100];
new SecureRandom(SEED).nextBytes(plaintext);
// Let's encrypt a simple plain text of size 100 bytes.
cryptoAsyncClient.encrypt(EncryptionAlgorithm.RSA_OAEP, plaintext)
.flatMap(encryptionResult -> {
System.out.printf("Returned ciphertext size is %d bytes with algorithm \"%s\"%n",
encryptionResult.getCipherText().length, encryptionResult.getAlgorithm());
//Let's decrypt the encrypted response.
return cryptoAsyncClient.decrypt(EncryptionAlgorithm.RSA_OAEP, encryptionResult.getCipherText());
}).subscribe(decryptionResult ->
System.out.printf("Returned plaintext size is %d bytes%n", decryptionResult.getPlainText().length));
疑难解答
有关如何诊断各种故障方案的详细信息,请参阅 故障排除指南 。
常规
Azure 密钥保管库 密钥客户端会引发异常。 例如,如果在删除某个密钥后尝试检索该密钥,则会返回一个 404
错误,指示找不到该资源。 以下代码片段通过捕获异常并显示有关错误的其他信息来妥善处理该错误。
try {
keyClient.getKey("<deleted-key-name>");
} catch (ResourceNotFoundException e) {
System.out.println(e.getMessage());
}
默认 HTTP 客户端
默认情况下,所有客户端库都使用 Netty HTTP 客户端。 添加上述依赖项会自动将客户端库配置为使用 Netty HTTP 客户端。 HTTP 客户端 Wiki 中详述了如何配置或更改 HTTP 客户端。
默认 SSL 库
默认情况下,所有客户端库均使用 Tomcat 原生 Boring SSL 库来为 SSL 操作启用原生级别性能。 无聊 SSL 库是一个 Uber JAR,包含适用于 Linux/macOS/Windows 的本机库,与 JDK 中的默认 SSL 实现相比,性能更佳。 有关详细信息(包括如何减小依赖项大小),请参阅 Wiki 的性能优化部分。
后续步骤
SDK 的 GitHub 存储库中提供了多个 Azure 密钥保管库 Java 客户端库示例。 这些示例提供了使用 Azure 密钥保管库 时经常遇到的其他方案的示例代码。
后续步骤示例
此处详细介绍了示例。
其他文档
有关 Azure 密钥保管库的更多文档,请参阅 API 参考文档。
贡献
本项目欢迎贡献和建议。 大多数贡献要求你同意贡献者许可协议 (CLA),并声明你有权(并且确实有权)授予我们使用你的贡献的权利。 有关详细信息,请访问 https://cla.microsoft.com 。
提交拉取请求时,CLA 机器人将自动确定你是否需要提供 CLA,并相应地修饰 PR(例如标签、注释)。 直接按机器人提供的说明操作。 只需使用 CLA 对所有存储库执行一次这样的操作。
此项目采用了 Microsoft 开放源代码行为准则。 有关详细信息,请参阅行为准则常见问题解答;若有其他任何问题或意见,请联系 opencode@microsoft.com。