Add this skill
npx mdskills install sickn33/azure-security-keyvault-keys-dotnetComprehensive Azure Key Vault cryptographic operations guide with excellent examples and best practices
1---2name: azure-security-keyvault-keys-dotnet3description: |4 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".5package: Azure.Security.KeyVault.Keys6---78# Azure.Security.KeyVault.Keys (.NET)910Client library for managing cryptographic keys in Azure Key Vault and Managed HSM.1112## Installation1314```bash15dotnet add package Azure.Security.KeyVault.Keys16dotnet add package Azure.Identity17```1819**Current Version**: 4.7.0 (stable)2021## Environment Variables2223```bash24KEY_VAULT_NAME=<your-key-vault-name>25# Or full URI26AZURE_KEYVAULT_URL=https://<vault-name>.vault.azure.net27```2829## Client Hierarchy3031```32KeyClient (key management)33├── CreateKey / CreateRsaKey / CreateEcKey34├── GetKey / GetKeys35├── UpdateKeyProperties36├── DeleteKey / PurgeDeletedKey37├── BackupKey / RestoreKey38└── GetCryptographyClient() → CryptographyClient3940CryptographyClient (cryptographic operations)41├── Encrypt / Decrypt42├── WrapKey / UnwrapKey43├── Sign / Verify44└── SignData / VerifyData4546KeyResolver (key resolution)47└── Resolve(keyId) → CryptographyClient48```4950## Authentication5152### DefaultAzureCredential (Recommended)5354```csharp55using Azure.Identity;56using Azure.Security.KeyVault.Keys;5758var keyVaultName = Environment.GetEnvironmentVariable("KEY_VAULT_NAME");59var kvUri = $"https://{keyVaultName}.vault.azure.net";6061var client = new KeyClient(new Uri(kvUri), new DefaultAzureCredential());62```6364### Service Principal6566```csharp67var credential = new ClientSecretCredential(68 tenantId: "<tenant-id>",69 clientId: "<client-id>",70 clientSecret: "<client-secret>");7172var client = new KeyClient(new Uri(kvUri), credential);73```7475## Key Management7677### Create Keys7879```csharp80// Create RSA key81KeyVaultKey rsaKey = await client.CreateKeyAsync("my-rsa-key", KeyType.Rsa);82Console.WriteLine($"Created key: {rsaKey.Name}, Type: {rsaKey.KeyType}");8384// Create RSA key with options85var rsaOptions = new CreateRsaKeyOptions("my-rsa-key-2048")86{87 KeySize = 2048,88 HardwareProtected = false, // true for HSM-backed89 ExpiresOn = DateTimeOffset.UtcNow.AddYears(1),90 NotBefore = DateTimeOffset.UtcNow,91 Enabled = true92};93rsaOptions.KeyOperations.Add(KeyOperation.Encrypt);94rsaOptions.KeyOperations.Add(KeyOperation.Decrypt);9596KeyVaultKey rsaKey2 = await client.CreateRsaKeyAsync(rsaOptions);9798// Create EC key99var ecOptions = new CreateEcKeyOptions("my-ec-key")100{101 CurveName = KeyCurveName.P256,102 HardwareProtected = true // HSM-backed103};104KeyVaultKey ecKey = await client.CreateEcKeyAsync(ecOptions);105106// Create Oct (symmetric) key for wrap/unwrap107var octOptions = new CreateOctKeyOptions("my-oct-key")108{109 KeySize = 256,110 HardwareProtected = true111};112KeyVaultKey octKey = await client.CreateOctKeyAsync(octOptions);113```114115### Retrieve Keys116117```csharp118// Get specific key (latest version)119KeyVaultKey key = await client.GetKeyAsync("my-rsa-key");120Console.WriteLine($"Key ID: {key.Id}");121Console.WriteLine($"Key Type: {key.KeyType}");122Console.WriteLine($"Version: {key.Properties.Version}");123124// Get specific version125KeyVaultKey keyVersion = await client.GetKeyAsync("my-rsa-key", "version-id");126127// List all keys128await foreach (KeyProperties keyProps in client.GetPropertiesOfKeysAsync())129{130 Console.WriteLine($"Key: {keyProps.Name}, Enabled: {keyProps.Enabled}");131}132133// List key versions134await foreach (KeyProperties version in client.GetPropertiesOfKeyVersionsAsync("my-rsa-key"))135{136 Console.WriteLine($"Version: {version.Version}, Created: {version.CreatedOn}");137}138```139140### Update Key Properties141142```csharp143KeyVaultKey key = await client.GetKeyAsync("my-rsa-key");144145key.Properties.ExpiresOn = DateTimeOffset.UtcNow.AddYears(2);146key.Properties.Tags["environment"] = "production";147148KeyVaultKey updatedKey = await client.UpdateKeyPropertiesAsync(key.Properties);149```150151### Delete and Purge Keys152153```csharp154// Start delete operation155DeleteKeyOperation operation = await client.StartDeleteKeyAsync("my-rsa-key");156157// Wait for deletion to complete (required before purge)158await operation.WaitForCompletionAsync();159Console.WriteLine($"Deleted key scheduled purge date: {operation.Value.ScheduledPurgeDate}");160161// Purge immediately (if soft-delete is enabled)162await client.PurgeDeletedKeyAsync("my-rsa-key");163164// Or recover deleted key165KeyVaultKey recoveredKey = await client.StartRecoverDeletedKeyAsync("my-rsa-key");166```167168### Backup and Restore169170```csharp171// Backup key172byte[] backup = await client.BackupKeyAsync("my-rsa-key");173await File.WriteAllBytesAsync("key-backup.bin", backup);174175// Restore key176byte[] backupData = await File.ReadAllBytesAsync("key-backup.bin");177KeyVaultKey restoredKey = await client.RestoreKeyBackupAsync(backupData);178```179180## Cryptographic Operations181182### Get CryptographyClient183184```csharp185// From KeyClient186KeyVaultKey key = await client.GetKeyAsync("my-rsa-key");187CryptographyClient cryptoClient = client.GetCryptographyClient(188 key.Name,189 key.Properties.Version);190191// Or create directly with key ID192CryptographyClient cryptoClient = new CryptographyClient(193 new Uri("https://myvault.vault.azure.net/keys/my-rsa-key/version"),194 new DefaultAzureCredential());195```196197### Encrypt and Decrypt198199```csharp200byte[] plaintext = Encoding.UTF8.GetBytes("Secret message to encrypt");201202// Encrypt203EncryptResult encryptResult = await cryptoClient.EncryptAsync(204 EncryptionAlgorithm.RsaOaep256,205 plaintext);206Console.WriteLine($"Encrypted: {Convert.ToBase64String(encryptResult.Ciphertext)}");207208// Decrypt209DecryptResult decryptResult = await cryptoClient.DecryptAsync(210 EncryptionAlgorithm.RsaOaep256,211 encryptResult.Ciphertext);212string decrypted = Encoding.UTF8.GetString(decryptResult.Plaintext);213Console.WriteLine($"Decrypted: {decrypted}");214```215216### Wrap and Unwrap Keys217218```csharp219// Key to wrap (e.g., AES key)220byte[] keyToWrap = new byte[32]; // 256-bit key221RandomNumberGenerator.Fill(keyToWrap);222223// Wrap key224WrapResult wrapResult = await cryptoClient.WrapKeyAsync(225 KeyWrapAlgorithm.RsaOaep256,226 keyToWrap);227228// Unwrap key229UnwrapResult unwrapResult = await cryptoClient.UnwrapKeyAsync(230 KeyWrapAlgorithm.RsaOaep256,231 wrapResult.EncryptedKey);232```233234### Sign and Verify235236```csharp237// Data to sign238byte[] data = Encoding.UTF8.GetBytes("Data to sign");239240// Sign data (computes hash internally)241SignResult signResult = await cryptoClient.SignDataAsync(242 SignatureAlgorithm.RS256,243 data);244245// Verify signature246VerifyResult verifyResult = await cryptoClient.VerifyDataAsync(247 SignatureAlgorithm.RS256,248 data,249 signResult.Signature);250Console.WriteLine($"Signature valid: {verifyResult.IsValid}");251252// Or sign pre-computed hash253using var sha256 = SHA256.Create();254byte[] hash = sha256.ComputeHash(data);255256SignResult signHashResult = await cryptoClient.SignAsync(257 SignatureAlgorithm.RS256,258 hash);259```260261## Key Resolver262263```csharp264using Azure.Security.KeyVault.Keys.Cryptography;265266var resolver = new KeyResolver(new DefaultAzureCredential());267268// Resolve key by ID to get CryptographyClient269CryptographyClient cryptoClient = await resolver.ResolveAsync(270 new Uri("https://myvault.vault.azure.net/keys/my-key/version"));271272// Use for encryption273EncryptResult result = await cryptoClient.EncryptAsync(274 EncryptionAlgorithm.RsaOaep256,275 plaintext);276```277278## Key Rotation279280```csharp281// Rotate key (creates new version)282KeyVaultKey rotatedKey = await client.RotateKeyAsync("my-rsa-key");283Console.WriteLine($"New version: {rotatedKey.Properties.Version}");284285// Get rotation policy286KeyRotationPolicy policy = await client.GetKeyRotationPolicyAsync("my-rsa-key");287288// Update rotation policy289policy.ExpiresIn = "P90D"; // 90 days290policy.LifetimeActions.Add(new KeyRotationLifetimeAction291{292 Action = KeyRotationPolicyAction.Rotate,293 TimeBeforeExpiry = "P30D" // Rotate 30 days before expiry294});295296await client.UpdateKeyRotationPolicyAsync("my-rsa-key", policy);297```298299## Key Types Reference300301| Type | Purpose |302|------|---------|303| `KeyClient` | Key management operations |304| `CryptographyClient` | Cryptographic operations |305| `KeyResolver` | Resolve key ID to CryptographyClient |306| `KeyVaultKey` | Key with cryptographic material |307| `KeyProperties` | Key metadata (no crypto material) |308| `CreateRsaKeyOptions` | RSA key creation options |309| `CreateEcKeyOptions` | EC key creation options |310| `CreateOctKeyOptions` | Symmetric key options |311| `EncryptResult` | Encryption result |312| `DecryptResult` | Decryption result |313| `SignResult` | Signing result |314| `VerifyResult` | Verification result |315| `WrapResult` | Key wrap result |316| `UnwrapResult` | Key unwrap result |317318## Algorithms Reference319320### Encryption Algorithms321| Algorithm | Key Type | Description |322|-----------|----------|-------------|323| `RsaOaep` | RSA | RSA-OAEP |324| `RsaOaep256` | RSA | RSA-OAEP-256 |325| `Rsa15` | RSA | RSA 1.5 (legacy) |326| `A128Gcm` | Oct | AES-128-GCM |327| `A256Gcm` | Oct | AES-256-GCM |328329### Signature Algorithms330| Algorithm | Key Type | Description |331|-----------|----------|-------------|332| `RS256` | RSA | RSASSA-PKCS1-v1_5 SHA-256 |333| `RS384` | RSA | RSASSA-PKCS1-v1_5 SHA-384 |334| `RS512` | RSA | RSASSA-PKCS1-v1_5 SHA-512 |335| `PS256` | RSA | RSASSA-PSS SHA-256 |336| `ES256` | EC | ECDSA P-256 SHA-256 |337| `ES384` | EC | ECDSA P-384 SHA-384 |338| `ES512` | EC | ECDSA P-521 SHA-512 |339340### Key Wrap Algorithms341| Algorithm | Key Type | Description |342|-----------|----------|-------------|343| `RsaOaep` | RSA | RSA-OAEP |344| `RsaOaep256` | RSA | RSA-OAEP-256 |345| `A128KW` | Oct | AES-128 Key Wrap |346| `A256KW` | Oct | AES-256 Key Wrap |347348## Best Practices3493501. **Use Managed Identity** — Prefer `DefaultAzureCredential` over secrets3512. **Enable soft-delete** — Protect against accidental deletion3523. **Use HSM-backed keys** — Set `HardwareProtected = true` for sensitive keys3534. **Implement key rotation** — Use automatic rotation policies3545. **Limit key operations** — Only enable required `KeyOperations`3556. **Set expiration dates** — Always set `ExpiresOn` for keys3567. **Use specific versions** — Pin to versions in production3578. **Cache CryptographyClient** — Reuse for multiple operations358359## Error Handling360361```csharp362using Azure;363364try365{366 KeyVaultKey key = await client.GetKeyAsync("my-key");367}368catch (RequestFailedException ex) when (ex.Status == 404)369{370 Console.WriteLine("Key not found");371}372catch (RequestFailedException ex) when (ex.Status == 403)373{374 Console.WriteLine("Access denied - check RBAC permissions");375}376catch (RequestFailedException ex)377{378 Console.WriteLine($"Key Vault error: {ex.Status} - {ex.Message}");379}380```381382## Required RBAC Roles383384| Role | Permissions |385|------|-------------|386| Key Vault Crypto Officer | Full key management |387| Key Vault Crypto User | Use keys for crypto operations |388| Key Vault Reader | Read key metadata |389390## Related SDKs391392| SDK | Purpose | Install |393|-----|---------|---------|394| `Azure.Security.KeyVault.Keys` | Keys (this SDK) | `dotnet add package Azure.Security.KeyVault.Keys` |395| `Azure.Security.KeyVault.Secrets` | Secrets | `dotnet add package Azure.Security.KeyVault.Secrets` |396| `Azure.Security.KeyVault.Certificates` | Certificates | `dotnet add package Azure.Security.KeyVault.Certificates` |397| `Azure.Identity` | Authentication | `dotnet add package Azure.Identity` |398399## Reference Links400401| Resource | URL |402|----------|-----|403| NuGet Package | https://www.nuget.org/packages/Azure.Security.KeyVault.Keys |404| API Reference | https://learn.microsoft.com/dotnet/api/azure.security.keyvault.keys |405| Quickstart | https://learn.microsoft.com/azure/key-vault/keys/quick-create-net |406| GitHub Source | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/keyvault/Azure.Security.KeyVault.Keys |407
Full transparency — inspect the skill content before installing.