你当前正在访问 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) 中都有相应的支持。 它提供创建、检索、更新、删除、清除、备份、还原以及列出密钥及其版本的操作。

源代码 | API 参考文档 | 产品文档 | 示例

入门

添加包

包括 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>

先决条件

验证客户端

若要与 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

曝光数