| name | azure-security-keyvault-keys-dotnet |
| description | Azure Key Vault Keys SDK for .NET. Client library for managing cryptographic keys in Azure Key Vault and Managed HSM. Use for key creation, rotation, encryption, decryption, signing, and verification. Triggers: "Key Vault keys", "KeyClient", "CryptographyClient", "RSA key", "EC key", "encrypt decrypt .NET", "key rotation", "HSM".
|
| license | MIT |
| metadata | {"author":"Microsoft","version":"1.0.0","package":"Azure.Security.KeyVault.Keys"} |
Azure.Security.KeyVault.Keys (.NET)
Client library for managing cryptographic keys in Azure Key Vault and Managed HSM.
Installation
dotnet add package Azure.Security.KeyVault.Keys
dotnet add package Azure.Identity
Current Version: 4.7.0 (stable)
Environment Variables
KEY_VAULT_NAME=<your-key-vault-name>
AZURE_KEYVAULT_URL=https://<vault-name>.vault.azure.net
AZURE_TOKEN_CREDENTIALS=prod
Client Hierarchy
KeyClient (key management)
├── CreateKey / CreateRsaKey / CreateEcKey
├── GetKey / GetKeys
├── UpdateKeyProperties
├── DeleteKey / PurgeDeletedKey
├── BackupKey / RestoreKey
└── GetCryptographyClient() → CryptographyClient
CryptographyClient (cryptographic operations)
├── Encrypt / Decrypt
├── WrapKey / UnwrapKey
├── Sign / Verify
└── SignData / VerifyData
KeyResolver (key resolution)
└── Resolve(keyId) → CryptographyClient
Authentication
Microsoft Entra Token Credential
using Azure.Identity;
using Azure.Security.KeyVault.Keys;
var keyVaultName = Environment.GetEnvironmentVariable("KEY_VAULT_NAME");
var kvUri = $"https://{keyVaultName}.vault.azure.net";
var credential = new DefaultAzureCredential(
DefaultAzureCredential.DefaultEnvironmentVariableName
);
var client = new KeyClient(new Uri(kvUri), credential);
Service Principal
var credential = new ClientSecretCredential(
tenantId: "<tenant-id>",
clientId: "<client-id>",
clientSecret: "<client-secret>");
var client = new KeyClient(new Uri(kvUri), credential);
Key Management
Create Keys
KeyVaultKey rsaKey = await client.CreateKeyAsync("my-rsa-key", KeyType.Rsa);
Console.WriteLine($"Created key: {rsaKey.Name}, Type: {rsaKey.KeyType}");
var rsaOptions = new CreateRsaKeyOptions("my-rsa-key-2048")
{
KeySize = 2048,
HardwareProtected = false,
ExpiresOn = DateTimeOffset.UtcNow.AddYears(1),
NotBefore = DateTimeOffset.UtcNow,
Enabled = true
};
rsaOptions.KeyOperations.Add(KeyOperation.Encrypt);
rsaOptions.KeyOperations.Add(KeyOperation.Decrypt);
KeyVaultKey rsaKey2 = await client.CreateRsaKeyAsync(rsaOptions);
var ecOptions = new CreateEcKeyOptions("my-ec-key")
{
CurveName = KeyCurveName.P256,
HardwareProtected = true
};
KeyVaultKey ecKey = await client.CreateEcKeyAsync(ecOptions);
var octOptions = new CreateOctKeyOptions("my-oct-key")
{
KeySize = 256,
HardwareProtected = true
};
KeyVaultKey octKey = await client.CreateOctKeyAsync(octOptions);
Retrieve Keys
KeyVaultKey key = await client.GetKeyAsync("my-rsa-key");
Console.WriteLine($"Key ID: {key.Id}");
Console.WriteLine($"Key Type: {key.KeyType}");
Console.WriteLine($"Version: {key.Properties.Version}");
KeyVaultKey keyVersion = await client.GetKeyAsync("my-rsa-key", "version-id");
await foreach (KeyProperties keyProps in client.GetPropertiesOfKeysAsync())
{
Console.WriteLine($"Key: {keyProps.Name}, Enabled: {keyProps.Enabled}");
}
await foreach (KeyProperties version in client.GetPropertiesOfKeyVersionsAsync("my-rsa-key"))
{
Console.WriteLine($"Version: {version.Version}, Created: {version.CreatedOn}");
}
Update Key Properties
KeyVaultKey key = await client.GetKeyAsync("my-rsa-key");
key.Properties.ExpiresOn = DateTimeOffset.UtcNow.AddYears(2);
key.Properties.Tags["environment"] = "production";
KeyVaultKey updatedKey = await client.UpdateKeyPropertiesAsync(key.Properties);
Delete and Purge Keys
DeleteKeyOperation operation = await client.StartDeleteKeyAsync("my-rsa-key");
await operation.WaitForCompletionAsync();
Console.WriteLine($"Deleted key scheduled purge date: {operation.Value.ScheduledPurgeDate}");
await client.PurgeDeletedKeyAsync("my-rsa-key");
KeyVaultKey recoveredKey = await client.StartRecoverDeletedKeyAsync("my-rsa-key");
Backup and Restore
byte[] backup = await client.BackupKeyAsync("my-rsa-key");
await File.WriteAllBytesAsync("key-backup.bin", backup);
byte[] backupData = await File.ReadAllBytesAsync("key-backup.bin");
KeyVaultKey restoredKey = await client.RestoreKeyBackupAsync(backupData);
Cryptographic Operations
Get CryptographyClient
KeyVaultKey key = await client.GetKeyAsync("my-rsa-key");
CryptographyClient cryptoClient = client.GetCryptographyClient(
key.Name,
key.Properties.Version);
CryptographyClient cryptoClient = new CryptographyClient(
new Uri("https://myvault.vault.azure.net/keys/my-rsa-key/version"),
new DefaultAzureCredential());
Encrypt and Decrypt
byte[] plaintext = Encoding.UTF8.GetBytes("Secret message to encrypt");
EncryptResult encryptResult = await cryptoClient.EncryptAsync(
EncryptionAlgorithm.RsaOaep256,
plaintext);
Console.WriteLine($"Encrypted: {Convert.ToBase64String(encryptResult.Ciphertext)}");
DecryptResult decryptResult = await cryptoClient.DecryptAsync(
EncryptionAlgorithm.RsaOaep256,
encryptResult.Ciphertext);
string decrypted = Encoding.UTF8.GetString(decryptResult.Plaintext);
Console.WriteLine($"Decrypted: {decrypted}");
Wrap and Unwrap Keys
byte[] keyToWrap = new byte[32];
RandomNumberGenerator.Fill(keyToWrap);
WrapResult wrapResult = await cryptoClient.WrapKeyAsync(
KeyWrapAlgorithm.RsaOaep256,
keyToWrap);
UnwrapResult unwrapResult = await cryptoClient.UnwrapKeyAsync(
KeyWrapAlgorithm.RsaOaep256,
wrapResult.EncryptedKey);
Sign and Verify
byte[] data = Encoding.UTF8.GetBytes("Data to sign");
SignResult signResult = await cryptoClient.SignDataAsync(
SignatureAlgorithm.RS256,
data);
VerifyResult verifyResult = await cryptoClient.VerifyDataAsync(
SignatureAlgorithm.RS256,
data,
signResult.Signature);
Console.WriteLine($"Signature valid: {verifyResult.IsValid}");
using var sha256 = SHA256.Create();
byte[] hash = sha256.ComputeHash(data);
SignResult signHashResult = await cryptoClient.SignAsync(
SignatureAlgorithm.RS256,
hash);
Key Resolver
using Azure.Security.KeyVault.Keys.Cryptography;
var resolver = new KeyResolver(new DefaultAzureCredential());
CryptographyClient cryptoClient = await resolver.ResolveAsync(
new Uri("https://myvault.vault.azure.net/keys/my-key/version"));
EncryptResult result = await cryptoClient.EncryptAsync(
EncryptionAlgorithm.RsaOaep256,
plaintext);
Key Rotation
KeyVaultKey rotatedKey = await client.RotateKeyAsync("my-rsa-key");
Console.WriteLine($"New version: {rotatedKey.Properties.Version}");
KeyRotationPolicy policy = await client.GetKeyRotationPolicyAsync("my-rsa-key");
policy.ExpiresIn = "P90D";
policy.LifetimeActions.Add(new KeyRotationLifetimeAction
{
Action = KeyRotationPolicyAction.Rotate,
TimeBeforeExpiry = "P30D"
});
await client.UpdateKeyRotationPolicyAsync("my-rsa-key", policy);
Key Types Reference
| Type | Purpose |
|---|
KeyClient | Key management operations |
CryptographyClient | Cryptographic operations |
KeyResolver | Resolve key ID to CryptographyClient |
KeyVaultKey | Key with cryptographic material |
KeyProperties | Key metadata (no crypto material) |
CreateRsaKeyOptions | RSA key creation options |
CreateEcKeyOptions | EC key creation options |
CreateOctKeyOptions | Symmetric key options |
EncryptResult | Encryption result |
DecryptResult | Decryption result |
SignResult | Signing result |
VerifyResult | Verification result |
WrapResult | Key wrap result |
UnwrapResult | Key unwrap result |
Algorithms Reference
Encryption Algorithms
| Algorithm | Key Type | Description |
|---|
RsaOaep | RSA | RSA-OAEP |
RsaOaep256 | RSA | RSA-OAEP-256 |
Rsa15 | RSA | RSA 1.5 (legacy) |
A128Gcm | Oct | AES-128-GCM |
A256Gcm | Oct | AES-256-GCM |
Signature Algorithms
| Algorithm | Key Type | Description |
|---|
RS256 | RSA | RSASSA-PKCS1-v1_5 SHA-256 |
RS384 | RSA | RSASSA-PKCS1-v1_5 SHA-384 |
RS512 | RSA | RSASSA-PKCS1-v1_5 SHA-512 |
PS256 | RSA | RSASSA-PSS SHA-256 |
ES256 | EC | ECDSA P-256 SHA-256 |
ES384 | EC | ECDSA P-384 SHA-384 |
ES512 | EC | ECDSA P-521 SHA-512 |
Key Wrap Algorithms
| Algorithm | Key Type | Description |
|---|
RsaOaep | RSA | RSA-OAEP |
RsaOaep256 | RSA | RSA-OAEP-256 |
A128KW | Oct | AES-128 Key Wrap |
A256KW | Oct | AES-256 Key Wrap |
Best Practices
- Use Managed Identity — Prefer
DefaultAzureCredential over secrets
- Enable soft-delete — Protect against accidental deletion
- Use HSM-backed keys — Set
HardwareProtected = true for sensitive keys
- Implement key rotation — Use automatic rotation policies
- Limit key operations — Only enable required
KeyOperations
- Set expiration dates — Always set
ExpiresOn for keys
- Use specific versions — Pin to versions in production
- Cache CryptographyClient — Reuse for multiple operations
Error Handling
using Azure;
try
{
KeyVaultKey key = await client.GetKeyAsync("my-key");
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
Console.WriteLine("Key not found");
}
catch (RequestFailedException ex) when (ex.Status == 403)
{
Console.WriteLine("Access denied - check RBAC permissions");
}
catch (RequestFailedException ex)
{
Console.WriteLine($"Key Vault error: {ex.Status} - {ex.Message}");
}
Required RBAC Roles
| Role | Permissions |
|---|
| Key Vault Crypto Officer | Full key management |
| Key Vault Crypto User | Use keys for crypto operations |
| Key Vault Reader | Read key metadata |
Related SDKs
| SDK | Purpose | Install |
|---|
Azure.Security.KeyVault.Keys | Keys (this SDK) | dotnet add package Azure.Security.KeyVault.Keys |
Azure.Security.KeyVault.Secrets | Secrets | dotnet add package Azure.Security.KeyVault.Secrets |
Azure.Security.KeyVault.Certificates | Certificates | dotnet add package Azure.Security.KeyVault.Certificates |
Azure.Identity | Authentication | dotnet add package Azure.Identity |
Reference Links