Azure Security Key Vault 密钥 Java SDK

azure-security-keyvault-keys-java
分类通用
作者Agentic Awesome Skills 社区
许可MIT
评分4.20/5
使用12.8K

Azure Key Vault Keys (Java)

在 Azure Key Vault 和 Managed HSM 中管理加密密钥并执行加密操作。

安装

xml
<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-security-keyvault-keys</artifactId>
    <version>4.9.0</version>
</dependency>

客户端创建

java
import com.azure.security.keyvault.keys.KeyClient;
import com.azure.security.keyvault.keys.KeyClientBuilder;
import com.azure.security.keyvault.keys.cryptography.CryptographyClient;
import com.azure.security.keyvault.keys.cryptography.CryptographyClientBuilder;
import com.azure.identity.DefaultAzureCredentialBuilder;

// 密钥管理客户端
KeyClient keyClient = new KeyClientBuilder()
.vaultUrl("https://<vault-name>.vault.azure.net")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();

// 异步客户端
KeyAsyncClient keyAsyncClient = new KeyClientBuilder()
.vaultUrl("https://<vault-name>.vault.azure.net")
.credential(new DefaultAzureCredentialBuilder().build())
.buildAsyncClient();

// 加密客户端 (用于加密/解密/签名/验证)
CryptographyClient cryptoClient = new CryptographyClientBuilder()
.keyIdentifier("https://<vault-name>.vault.azure.net/keys/<key-name>/<key-version>")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();

密钥类型

| 类型 | 描述 |
|------|-------------|
| RSA | RSA 密钥 (2048, 3072, 4096 位) |
| RSA_HSM | HSM 中的 RSA 密钥 |
| EC | 椭圆曲线 (EC) 密钥 |
| EC_HSM | HSM 中的椭圆曲线 (EC) 密钥 |
| OCT | 对称密钥 (仅限 Managed HSM) |
| OCT_HSM | HSM 中的对称密钥 |

创建密钥

创建 RSA 密钥

java
import com.azure.security.keyvault.keys.models.*;

// 简单 RSA 密钥
KeyVaultKey rsaKey = keyClient.createRsaKey(new CreateRsaKeyOptions("my-rsa-key")
.setKeySize(2048));

System.out.println("Key name: " + rsaKey.getName());
System.out.println("Key ID: " + rsaKey.getId());
System.out.println("Key type: " + rsaKey.getKeyType());

// 带选项的 RSA 密钥
KeyVaultKey rsaKeyWithOptions = keyClient.createRsaKey(new CreateRsaKeyOptions("my-rsa-key-2")
.setKeySize(4096)
.setExpiresOn(OffsetDateTime.now().plusYears(1))
.setNotBefore(OffsetDateTime.now())
.setEnabled(true)
.setKeyOperations(KeyOperation.ENCRYPT, KeyOperation.DECRYPT,
KeyOperation.WRAP_KEY, KeyOperation.UNWRAP_KEY)
.setTags(Map.of("environment", "production")));

// HSM 备份的 RSA 密钥
KeyVaultKey hsmKey = keyClient.createRsaKey(new CreateRsaKeyOptions("my-hsm-key")
.setKeySize(2048)
.setHardwareProtected(true));

创建 EC 密钥

java
// 使用 P-256 曲线的 EC 密钥
KeyVaultKey ecKey = keyClient.createEcKey(new CreateEcKeyOptions("my-ec-key")
    .setCurveName(KeyCurveName.P_256));

// 使用其他曲线的 EC 密钥
KeyVaultKey ecKey384 = keyClient.createEcKey(new CreateEcKeyOptions("my-ec-key-384")
.setCurveName(KeyCurveName.P_384));

KeyVaultKey ecKey521 = keyClient.createEcKey(new CreateEcKeyOptions("my-ec-key-521")
.setCurveName(KeyCurveName.P_521));

// HSM 备份的 EC 密钥
KeyVaultKey ecHsmKey = keyClient.createEcKey(new Creat


eEcKeyOptions("my-ec-hsm-key")
.setCurveName(KeyCurveName.P_256)
.setHardwareProtected(true));
code
### 创建对称密钥(仅限 Managed HSM)
java
KeyVaultKey octKey = keyClient.createOctKey(new CreateOctKeyOptions("my-symmetric-key")
.setKeySize(256)
.setHardwareProtected(true));
code
## 获取密钥
java
// 获取最新版本
KeyVaultKey key = keyClient.getKey("my-key");

// 获取特定版本
KeyVaultKey keyVersion = keyClient.getKey("my-key", "<version-id>");

// 仅获取密钥属性(不含密钥材料)
KeyProperties keyProps = keyClient.getKey("my-key").getProperties();

code
## 更新密钥属性
java
KeyVaultKey key = keyClient.getKey("my-key");

// 更新属性
key.getProperties()
.setEnabled(false)
.setExpiresOn(OffsetDateTime.now().plusMonths(6))
.setTags(Map.of("status", "archived"));

KeyVaultKey updatedKey = keyClient.updateKeyProperties(key.getProperties(),
KeyOperation.ENCRYPT, KeyOperation.DECRYPT);

code
## 列出密钥
java
import com.azure.core.util.paging.PagedIterable;

// 列出所有密钥
for (KeyProperties keyProps : keyClient.listPropertiesOfKeys()) {
System.out.println("Key: " + keyProps.getName());
System.out.println(" Enabled: " + keyProps.isEnabled());
System.out.println(" Created: " + keyProps.getCreatedOn());
}

// 列出密钥版本
for (KeyProperties version : keyClient.listPropertiesOfKeyVersions("my-key")) {
System.out.println("Version: " + version.getVersion());
System.out.println("Created: " + version.getCreatedOn());
}

code
## 删除密钥
java
import com.azure.core.util.polling.SyncPoller;

// 开始删除(适用于启用软删除的存储库)
SyncPoller<DeletedKey, Void> deletePoller = keyClient.beginDeleteKey("my-key");

// 等待删除完成
DeletedKey deletedKey = deletePoller.poll().getValue();
System.out.println("Deleted: " + deletedKey.getDeletedOn());

deletePoller.waitForCompletion();

// 清除已删除的密钥(永久删除)
keyClient.purgeDeletedKey("my-key");

// 恢复已删除的密钥
SyncPoller<KeyVaultKey, Void> recoverPoller = keyClient.beginRecoverDeletedKey("my-key");
recoverPoller.waitForCompletion();

code
## 加密操作

加密/解密

java import com.azure.security.keyvault.keys.cryptography.models.*;

CryptographyClient cryptoClient = new CryptographyClientBuilder()
.keyIdentifier("https://<vault>.vault.azure.net/keys/<key-name>")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();

byte[] plaintext = "Hello, World!".getBytes(StandardCharsets.UTF_8);

// 加密
EncryptResult encryptResult = cryptoClient.encrypt(EncryptionAlgorithm.RSA_OAEP, plaintext);
byte[] ciphertext = encryptResult.getCipherText();
System.out.println("Ciphertext length: " + ciphertext.length);

// 解密
DecryptResult decryptResult = cryptoClient.decrypt(EncryptionAlgorithm.RSA_OAEP, ciphertext);
String decrypted = new String(decryptResult.getPlainText(), StandardCharsets.UTF_8);
System.out.println("Decrypted: " + decrypted);

code
### 签名/验证
java
import java.security.MessageDigest;

// 创建数据的摘要
byte[] data = "Data to sign".getBytes(StandardCharsets.UTF_8);
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(data);

// 签名
SignResult signResult = cryptoClient.sign(SignatureAlgorithm.RS256, digest);
byte[] signature = signResult.getSignature();

// 验证
VerifyResult verifyResult = cryptoClient.verify(SignatureAlgorithm.RS256, digest, signat

code
ure);
System.out.println("Valid signature: " + verifyResult.isValid());

密钥包裹/解包裹 (Wrap/Unwrap Key)

java
// 要包裹的密钥(例如 AES 密钥)
byte[] keyToWrap = new byte[32];  // 256 位密钥
new SecureRandom().nextBytes(keyToWrap);

// 包裹 (Wrap)
WrapResult wrapResult = cryptoClient.wrapKey(KeyWrapAlgorithm.RSA_OAEP, keyToWrap);
byte[] wrappedKey = wrapResult.getEncryptedKey();

// 解包裹 (Unwrap)
UnwrapResult unwrapResult = cryptoClient.unwrapKey(KeyWrapAlgorithm.RSA_OAEP, wrappedKey);
byte[] unwrappedKey = unwrapResult.getKey();

备份与还原

java
// 备份
byte[] backup = keyClient.backupKey("my-key");

// 将备份保存到文件
Files.write(Paths.get("key-backup.blob"), backup);

// 还原
byte[] backupData = Files.readAllBytes(Paths.get("key-backup.blob"));
KeyVaultKey restoredKey = keyClient.restoreKeyBackup(backupData);

密钥轮转 (Key Rotation)

java
// 轮转至新版本
KeyVaultKey rotatedKey = keyClient.rotateKey("my-key");
System.out.println("New version: " + rotatedKey.getProperties().getVersion());

// 设置轮转策略
KeyRotationPolicy policy = new KeyRotationPolicy()
.setExpiresIn("P90D") // 90 天后过期
.setLifetimeActions(Arrays.asList(
new KeyRotationLifetimeAction(KeyRotationPolicyAction.ROTATE)
.setTimeBeforeExpiry("P30D"))); // 在过期前 30 天进行轮转

keyClient.updateKeyRotationPolicy("my-key", policy);

// 获取轮转策略
KeyRotationPolicy currentPolicy = keyClient.getKeyRotationPolicy("my-key");

导入密钥

java
import com.azure.security.keyvault.keys.models.ImportKeyOptions;
import com.azure.security.keyvault.keys.models.JsonWebKey;

// 导入现有密钥材料
JsonWebKey jsonWebKey = new JsonWebKey()
.setKeyType(KeyType.RSA)
.setN(modulus)
.setE(exponent)
.setD(privateExponent)
// ... 其他 RSA 组件
;

ImportKeyOptions importOptions = new ImportKeyOptions("imported-key", jsonWebKey)
.setHardwareProtected(false);

KeyVaultKey importedKey = keyClient.importKey(importOptions);

加密算法

| 算法 | 密钥类型 | 描述 |
|-----------|----------|-------------|
| RSA1_5 | RSA | RSAES-PKCS1-v1_5 |
| RSA_OAEP | RSA | 带有 OAEP 的 RSAES(推荐) |
| RSA_OAEP_256 | RSA | 使用 SHA-256 的带有 OAEP 的 RSAES |
| A128GCM | OCT | AES-GCM 128 位 |
| A256GCM | OCT | AES-GCM 256 位 |
| A128CBC | OCT | AES-CBC 128 位 |
| A256CBC | OCT | AES-CBC 256 位 |

签名算法

| 算法 | 密钥类型 | 哈希算法 |
|-----------|----------|------|
| RS256 | RSA | SHA-256 |
| RS384 | RSA | SHA-384 |
| RS512 | RSA | SHA-512 |
| PS256 | RSA | SHA-256 (PSS) |
| ES256 | EC P-256 | SHA-256 |
| ES384 | EC P-384 | SHA-384 |
| ES512 | EC P-521 | SHA-512 |

错误处理

java
import com.azure.core.exception.HttpResponseException;
import com.azure.core.exception.ResourceNotFoundException;

try {
KeyVaultKey key = keyClient.getKey("non-existent-key");
} catch (ResourceNotFoundException e) {
System.out.println("Key not found: " + e.getMessage());
} catch (HttpResponseException e) {
System.out.println("HTTP error " + e.getResponse().getStatusCode());
System.out.println("Message: " + e.getMessage());
}

环境变量

bash
AZURE_KEYVAULT_URL=https://<vault-name>.vault.azure.net

最佳实践

1. 生产环境使用 HSM 密钥 - 为敏感密钥设置 setHardwareProtected(true)
2. 启用软删除 (Soft Delete) - 防止意外删除
3. 密钥
轮换 (Rotation) - 设置自动轮换策略
4. 最小特权 (Least Privilege) - 为不同操作使用独立的密钥
5. 尽可能在本地加密 (Local Crypto When Possible) - 使用带有本地密钥材料的 CryptographyClient 以减少往返请求

触发词

  • "Key Vault keys Java", "cryptographic keys Java"
  • "encrypt decrypt Java", "sign verify Java"
  • "RSA key", "EC key", "HSM key"
  • "key rotation", "wrap unwrap key"

使用场景

本技能适用于执行概览中所描述的工作流或操作。

局限性

  • 仅在任务明确符合上述范围时使用此技能。
  • 不要将输出结果视为针对特定环境的验证、测试或专家评审的替代方案。
  • 如果缺失必要的输入、权限、安全边界或成功标准,请停止并请求澄清。