Inhaltsverzeichnis

Azure Key Vault

Cloud: Microsoft Azure
HSM-Level: FIPS 140-2 Level 2 (Standard) / Level 3 (Managed HSM)
PQ-Support: Noch nicht verfügbar (Stand 2024)

Integration von Azure Key Vault für Zertifikats- und Schlüsselmanagement.


Architektur

flowchart TB subgraph AZURE["☁️ AZURE"] subgraph KV["Key Vault"] K[Keys] S[Secrets] C[Certificates] end subgraph HSM["Managed HSM"] H[HSM Keys] end subgraph APPS["Applications"] A1[App Service] A2[AKS] A3[Functions] end end subgraph ONPREM["🏢 ON-PREM"] CA[Internal CA] end CA -->|Import| C K --> A1 & A2 & A3 C --> A1 & A2 & A3 H -->|Premium| K style KV fill:#e3f2fd style HSM fill:#e8f5e9


Setup

Key Vault erstellen

# Azure CLI
az login
 
# Resource Group
az group create --name rg-pki --location germanywestcentral
 
# Key Vault (Standard)
az keyvault create \
    --name kv-pki-prod \
    --resource-group rg-pki \
    --location germanywestcentral \
    --sku standard
 
# Key Vault (Premium mit HSM)
az keyvault create \
    --name kv-pki-prod-hsm \
    --resource-group rg-pki \
    --location germanywestcentral \
    --sku premium

Managed HSM (FIPS 140-2 Level 3)

# Managed HSM erstellen
az keyvault create \
    --hsm-name hsm-pki-prod \
    --resource-group rg-pki \
    --location germanywestcentral \
    --administrators "user@example.com"
 
# HSM aktivieren (erfordert 3 RSA Keys)
az keyvault security-domain download \
    --hsm-name hsm-pki-prod \
    --sd-wrapping-keys key1.pem key2.pem key3.pem \
    --sd-quorum 2 \
    --security-domain-file sd.json

Zertifikate verwalten

Zertifikat importieren

# PFX-Zertifikat importieren
az keyvault certificate import \
    --vault-name kv-pki-prod \
    --name server-cert \
    --file server.pfx \
    --password "pfx-password"
// C# - Zertifikat importieren
using Azure.Identity;
using Azure.Security.KeyVault.Certificates;
 
var client = new CertificateClient(
    new Uri("https://kv-pki-prod.vault.azure.net/"),
    new DefaultAzureCredential());
 
// PFX importieren
byte[] pfxData = File.ReadAllBytes("server.pfx");
var importOptions = new ImportCertificateOptions("server-cert", pfxData)
{
    Password = "pfx-password"
};
 
KeyVaultCertificateWithPolicy cert = await client.ImportCertificateAsync(importOptions);
Console.WriteLine($"Importiert: {cert.Name}, Thumbprint: {cert.Properties.X509Thumbprint}");

Zertifikat abrufen

// C# - Zertifikat aus Key Vault laden
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using System.Security.Cryptography.X509Certificates;
 
var secretClient = new SecretClient(
    new Uri("https://kv-pki-prod.vault.azure.net/"),
    new DefaultAzureCredential());
 
// Zertifikat als Secret abrufen (enthält Private Key)
KeyVaultSecret secret = await secretClient.GetSecretAsync("server-cert");
 
byte[] certBytes = Convert.FromBase64String(secret.Value);
var certificate = new X509Certificate2(certBytes);
 
Console.WriteLine($"Subject: {certificate.Subject}");
Console.WriteLine($"Has Private Key: {certificate.HasPrivateKey}");

Zertifikat mit Key Vault CA erstellen

# Zertifikatsrichtlinie definieren
az keyvault certificate create \
    --vault-name kv-pki-prod \
    --name app-cert \
    --policy @cert-policy.json
// cert-policy.json
{
  "issuerParameters": {
    "name": "Self"
  },
  "keyProperties": {
    "exportable": true,
    "keySize": 4096,
    "keyType": "RSA",
    "reuseKey": false
  },
  "secretProperties": {
    "contentType": "application/x-pkcs12"
  },
  "x509CertificateProperties": {
    "subject": "CN=app.example.com",
    "subjectAlternativeNames": {
      "dnsNames": ["app.example.com", "*.app.example.com"]
    },
    "validityInMonths": 12
  }
}

Schlüssel für Signing

Signing Key erstellen

# EC Key für Signaturen
az keyvault key create \
    --vault-name kv-pki-prod \
    --name signing-key \
    --kty EC \
    --curve P-384
 
# RSA Key
az keyvault key create \
    --vault-name kv-pki-prod \
    --name rsa-signing-key \
    --kty RSA \
    --size 4096

Remote Signing

// C# - Signieren mit Azure Key Vault Key
using Azure.Identity;
using Azure.Security.KeyVault.Keys;
using Azure.Security.KeyVault.Keys.Cryptography;
 
var keyClient = new KeyClient(
    new Uri("https://kv-pki-prod.vault.azure.net/"),
    new DefaultAzureCredential());
 
KeyVaultKey key = await keyClient.GetKeyAsync("signing-key");
var cryptoClient = new CryptographyClient(key.Id, new DefaultAzureCredential());
 
// Daten signieren
byte[] dataToSign = Encoding.UTF8.GetBytes("Important document");
byte[] digest = SHA384.HashData(dataToSign);
 
SignResult signature = await cryptoClient.SignAsync(
    SignatureAlgorithm.ES384,
    digest);
 
Console.WriteLine($"Signatur: {Convert.ToBase64String(signature.Signature)}");
 
// Signatur verifizieren
VerifyResult verified = await cryptoClient.VerifyAsync(
    SignatureAlgorithm.ES384,
    digest,
    signature.Signature);
 
Console.WriteLine($"Verifiziert: {verified.IsValid}");

App Service / AKS Integration

App Service

# Key Vault Reference in App Settings
az webapp config appsettings set \
    --name myapp \
    --resource-group rg-app \
    --settings "Certificate=@Microsoft.KeyVault(VaultName=kv-pki-prod;SecretName=server-cert)"
 
# Managed Identity aktivieren
az webapp identity assign \
    --name myapp \
    --resource-group rg-app
 
# Key Vault Access Policy
az keyvault set-policy \
    --name kv-pki-prod \
    --object-id <managed-identity-object-id> \
    --secret-permissions get list \
    --certificate-permissions get list

Azure Kubernetes Service (AKS)

# secrets-store-csi-driver.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: azure-keyvault-tls
spec:
  provider: azure
  parameters:
    usePodIdentity: "false"
    useVMManagedIdentity: "true"
    userAssignedIdentityID: "<client-id>"
    keyvaultName: "kv-pki-prod"
    objects: |
      array:
        - |
          objectName: server-cert
          objectType: secret
    tenantId: "<tenant-id>"
  secretObjects:
    - secretName: tls-secret
      type: kubernetes.io/tls
      data:
        - objectName: server-cert
          key: tls.crt
        - objectName: server-cert
          key: tls.key
# pod-with-keyvault-cert.yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-with-tls
spec:
  containers:
    - name: app
      image: myapp:latest
      volumeMounts:
        - name: secrets-store
          mountPath: "/mnt/secrets-store"
          readOnly: true
  volumes:
    - name: secrets-store
      csi:
        driver: secrets-store.csi.k8s.io
        readOnly: true
        volumeAttributes:
          secretProviderClass: "azure-keyvault-tls"

Monitoring

# Diagnostics aktivieren
az monitor diagnostic-settings create \
    --name kv-diagnostics \
    --resource /subscriptions/<sub>/resourceGroups/rg-pki/providers/Microsoft.KeyVault/vaults/kv-pki-prod \
    --logs '[{"category": "AuditEvent", "enabled": true}]' \
    --metrics '[{"category": "AllMetrics", "enabled": true}]' \
    --workspace <log-analytics-workspace-id>

KQL Query für Zertifikatsoperationen:

AzureDiagnostics
| where ResourceProvider == "MICROSOFT.KEYVAULT"
| where OperationName contains "Certificate"
| project TimeGenerated, OperationName, ResultType, CallerIPAddress, identity_claim_upn_s
| order by TimeGenerated desc

Checkliste

# Prüfpunkt
———–
1 Key Vault erstellt
2 Access Policies konfiguriert
3 Zertifikate importiert
4 Managed Identity für Apps
5 Diagnostics aktiviert
6 Backup konfiguriert

Verwandte Dokumentation


« ← Cloud Integration | → AWS KMS »


Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional