Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Azure Key Vault Keys Java SDK for cryptographic key management. Use when creating, managing, or using RSA/EC keys, performing encrypt/decrypt/sign/verify operations, or working with HSM-backed keys.
.claude/skills/microsoft-azure-security-keyvault-keys-java/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 177% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 165% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 108% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 129% | 0% |
Manage cryptographic keys and perform cryptographic operations in Azure Key Vault and Managed HSM.
xml<dependency> <groupId>com.azure</groupId> <artifactId>azure-security-keyvault-keys</artifactId> <version>4.9.0</version> </dependency>
javaimport com.azure.core.credential.TokenCredential; import com.azure.identity.AzureIdentityEnvVars; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.identity.ManagedIdentityCredentialBuilder; 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; // Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential> TokenCredential credential = new DefaultAzureCredentialBuilder() .requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS) .build(); // Or use a specific credential directly in production: // See https://learn.microsoft.com/java/api/overview/azure/identity-readme?view=azure-java-stable#credential-classes // TokenCredential credential = new ManagedIdentityCredentialBuilder().build(); // Key management client KeyClient keyClient = new KeyClientBuilder() .vaultUrl("https://<vault-name>.vault.azure.net") .credential(credential) .buildClient(); // Async client KeyAsyncClient keyAsyncClient = new KeyClientBuilder() .vaultUrl("https://<vault-name>.vault.azure.net") .credential(credential) .buildAsyncClient(); // Cryptography client (for encrypt/decrypt/sign/verify) CryptographyClient cryptoClient = new CryptographyClientBuilder() .keyIdentifier("https://<vault-name>.vault.azure.net/keys/<key-name>/<key-version>") .credential(credential) .buildClient();
| Type | Description | |------|-------------| | RSA | RSA key (2048, 3072, 4096 bits) | | RSA_HSM | RSA key in HSM | | EC | Elliptic Curve key | | EC_HSM | Elliptic Curve key in HSM | | OCT | Symmetric key (Managed HSM only) | | OCT_HSM | Symmetric key in HSM |
javaimport com.azure.security.keyvault.keys.models.*; // Simple RSA key 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 key with options 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-backed RSA key KeyVaultKey hsmKey = keyClient.createRsaKey(new CreateRsaKeyOptions("my-hsm-key") .setKeySize(2048) .setHardwareProtected(true));
java// EC key with P-256 curve KeyVaultKey ecKey = keyClient.createEcKey(new CreateEcKeyOptions("my-ec-key") .setCurveName(KeyCurveName.P_256)); // EC key with other curves 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-backed EC key KeyVaultKey ecHsmKey = keyClient.createEcKey(new CreateEcKeyOptions("my-ec-hsm-key") .setCurveName(KeyCurveName.P_256) .setHardwareProtected(true));
javaKeyVaultKey octKey = keyClient.createOctKey(new CreateOctKeyOptions("my-symmetric-key") .setKeySize(256) .setHardwareProtected(true));
java// Get latest version KeyVaultKey key = keyClient.getKey("my-key"); // Get specific version KeyVaultKey keyVersion = keyClient.getKey("my-key", "<version-id>"); // Get only key properties (no key material) KeyProperties keyProps = keyClient.getKey("my-key").getProperties();
javaKeyVaultKey key = keyClient.getKey("my-key"); // Update properties key.getProperties() .setEnabled(false) .setExpiresOn(OffsetDateTime.now().plusMonths(6)) .setTags(Map.of("status", "archived")); KeyVaultKey updatedKey = keyClient.updateKeyProperties(key.getProperties(), KeyOperation.ENCRYPT, KeyOperation.DECRYPT);
javaimport com.azure.core.util.paging.PagedIterable; // List all keys for (KeyProperties keyProps : keyClient.listPropertiesOfKeys()) { System.out.println("Key: " + keyProps.getName()); System.out.println(" Enabled: " + keyProps.isEnabled()); System.out.println(" Created: " + keyProps.getCreatedOn()); } // List key versions for (KeyProperties version : keyClient.listPropertiesOfKeyVersions("my-key")) { System.out.println("Version: " + version.getVersion()); System.out.println("Created: " + version.getCreatedOn()); }
javaimport com.azure.core.util.polling.SyncPoller; // Begin delete (soft-delete enabled vaults) SyncPoller<DeletedKey, Void> deletePoller = keyClient.beginDeleteKey("my-key"); // Wait for deletion DeletedKey deletedKey = deletePoller.poll().getValue(); System.out.println("Deleted: " + deletedKey.getDeletedOn()); deletePoller.waitForCompletion(); // Purge deleted key (permanent deletion) keyClient.purgeDeletedKey("my-key"); // Recover deleted key SyncPoller<KeyVaultKey, Void> recoverPoller = keyClient.beginRecoverDeletedKey("my-key"); recoverPoller.waitForCompletion();
javaimport 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); // Encrypt EncryptResult encryptResult = cryptoClient.encrypt(EncryptionAlgorithm.RSA_OAEP, plaintext); byte[] ciphertext = encryptResult.getCipherText(); System.out.println("Ciphertext length: " + ciphertext.length); // Decrypt DecryptResult decryptResult = cryptoClient.decrypt(EncryptionAlgorithm.RSA_OAEP, ciphertext); String decrypted = new String(decryptResult.getPlainText(), StandardCharsets.UTF_8); System.out.println("Decrypted: " + decrypted);
javaimport java.security.MessageDigest; // Create digest of data byte[] data = "Data to sign".getBytes(StandardCharsets.UTF_8); MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] digest = md.digest(data); // Sign SignResult signResult = cryptoClient.sign(SignatureAlgorithm.RS256, digest); byte[] signature = signResult.getSignature(); // Verify VerifyResult verifyResult = cryptoClient.verify(SignatureAlgorithm.RS256, digest, signature); System.out.println("Valid signature: " + verifyResult.isValid());
java// Key to wrap (e.g., AES key) byte[] keyToWrap = new byte[32]; // 256-bit key 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// Backup byte[] backup = keyClient.backupKey("my-key"); // Save backup to file Files.write(Paths.get("key-backup.blob"), backup); // Restore byte[] backupData = Files.readAllBytes(Paths.get("key-backup.blob")); KeyVaultKey restoredKey = keyClient.restoreKeyBackup(backupData);
java// Rotate to new version KeyVaultKey rotatedKey = keyClient.rotateKey("my-key"); System.out.println("New version: " + rotatedKey.getProperties().getVersion()); // Set rotation policy KeyRotationPolicy policy = new KeyRotationPolicy() .setExpiresIn("P90D") // Expire after 90 days .setLifetimeActions(Arrays.asList( new KeyRotationLifetimeAction(KeyRotationPolicyAction.ROTATE) .setTimeBeforeExpiry("P30D"))); // Rotate 30 days before expiry keyClient.updateKeyRotationPolicy("my-key", policy); // Get rotation policy KeyRotationPolicy currentPolicy = keyClient.getKeyRotationPolicy("my-key");
javaimport com.azure.security.keyvault.keys.models.ImportKeyOptions; import com.azure.security.keyvault.keys.models.JsonWebKey; // Import existing key material JsonWebKey jsonWebKey = new JsonWebKey() .setKeyType(KeyType.RSA) .setN(modulus) .setE(exponent) .setD(privateExponent) // ... other RSA components ; ImportKeyOptions importOptions = new ImportKeyOptions("imported-key", jsonWebKey) .setHardwareProtected(false); KeyVaultKey importedKey = keyClient.importKey(importOptions);
| Algorithm | Key Type | Description | |-----------|----------|-------------| | RSA1_5 | RSA | RSAES-PKCS1-v1_5 | | RSA_OAEP | RSA | RSAES with OAEP (recommended) | | RSA_OAEP_256 | RSA | RSAES with OAEP using SHA-256 | | A128GCM | OCT | AES-GCM 128-bit | | A256GCM | OCT | AES-GCM 256-bit | | A128CBC | OCT | AES-CBC 128-bit | | A256CBC | OCT | AES-CBC 256-bit |
| Algorithm | Key Type | Hash | |-----------|----------|------| | 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 |
javaimport 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()); }
bashAZURE_KEYVAULT_URL=https://<vault-name>.vault.azure.net # Required for vault URL AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production
setHardwareProtected(true) for sensitive keysCryptographyClient with local key material to reduce round-trips| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 11,280 | 7,986 | -29% | 1 | 1 | 0% | 2,623 | 5,393 | +106% | 0 | 0 | — |
case-02 | fail→fail | 13,841 | 10,011 | -28% | 1 | 1 | 0% | 2,879 | 5,808 | +102% | 0 | 0 | — |
case-03 | fail→pass | 8,167 | 6,230 | -24% | 1 | 1 | 0% | 1,728 | 4,793 | +177% | 0 | 0 | — |
case-04 | pass→pass | 12,755 | 11,042 | -13% | 1 | 1 | 0% | 2,803 | 5,960 | +113% | 0 | 0 | — |
case-05 | fail→fail | 12,779 | 10,861 | -15% | 1 | 1 | 0% | 2,867 | 5,743 | +100% | 0 | 0 | — |
case-06 | fail→pass | 8,662 | 5,970 | -31% | 1 | 1 | 0% | 1,788 | 4,745 | +165% | 0 | 0 | — |
case-07 | fail→pass | 10,626 | 6,470 | -39% | 1 | 1 | 0% | 2,338 | 4,853 | +108% | 0 | 0 | — |
case-08 | pass→pass | 6,608 | 3,159 | -52% | 1 | 1 | 0% | 1,469 | 4,100 | +179% | 0 | 0 | — |
case-09 | fail→pass | 12,948 | 4,678 | -64% | 1 | 1 | 0% | 3,014 | 4,459 | +48% | 0 | 0 | — |
case-10 | pass→pass | 7,632 | 5,051 | -34% | 1 | 1 | 0% | 1,736 | 4,459 | +157% | 0 | 0 | — |
case-11 | pass→pass | 9,363 | 4,332 | -54% | 1 | 1 | 0% | 2,157 | 4,351 | +102% | 0 | 0 | — |
case-12 | pass→pass | 11,062 | 5,036 | -54% | 1 | 1 | 0% | 2,429 | 4,559 | +88% | 0 | 0 | — |
case-13 | fail→pass | 8,997 | 4,965 | -45% | 1 | 1 | 0% | 1,999 | 4,573 | +129% | 0 | 0 | — |
case-14 | pass→pass | 9,203 | 4,992 | -46% | 1 | 1 | 0% | 2,041 | 4,466 | +119% | 0 | 0 | — |
case-15 | pass→pass | 12,366 | 6,195 | -50% | 1 | 1 | 0% | 2,830 | 5,009 | +77% | 0 | 0 | — |
case-16 | fail→fail | 10,169 | 5,739 | -44% | 1 | 1 | 0% | 2,241 | 4,848 | +116% | 0 | 0 | — |
case-17 | fail→pass | 8,652 | 2,822 | -67% | 1 | 1 | 0% | 2,026 | 4,027 | +99% | 0 | 0 | — |
case-18 | pass→pass | 12,802 | 4,791 | -63% | 1 | 1 | 0% | 2,895 | 4,510 | +56% | 0 | 0 | — |
case-19 | fail→pass | 10,316 | 5,511 | -47% | 1 | 1 | 0% | 2,351 | 4,617 | +96% | 0 | 0 | — |
case-20 | fail→pass | 6,168 | 6,389 | +4% | 1 | 1 | 0% | 1,409 | 4,735 | +236% | 0 | 0 | — |
case-21 | pass→pass | 9,029 | 3,638 | -60% | 1 | 1 | 0% | 1,925 | 4,190 | +118% | 0 | 0 | — |
case-22 | pass→pass | 9,295 | 4,845 | -48% | 1 | 1 | 0% | 2,206 | 4,584 | +108% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +36 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.