Inhaltsverzeichnis

Azure Key Vault

Oblak: Microsoft Azure
HSM nivo: FIPS 140-2 Nivo 2 (Standard) / Nivo 3 (Managed HSM)
PQ podpora: Še ni na voljo (stanje 2024)

Integracija Azure Key Vault za upravljanje certifikatov in ključev.


Arhitektura

flowchart TB subgraph AZURE["AZURE"] subgraph KV["Key Vault"] K[Ključi] S[Skrivnosti] C[Certifikati] end subgraph HSM["Managed HSM"] H[HSM ključi] end subgraph APPS["Aplikacije"] A1[App Service] A2[AKS] A3[Functions] end end subgraph ONPREM["NA LOKACIJI"] CA[Notranji CA] end CA -->|Uvoz| C K --> A1 & A2 & A3 C --> A1 & A2 & A3 H -->|Premium| K style KV fill:#e3f2fd style HSM fill:#e8f5e9


Nastavitev

Ustvarjanje Key Vault

# 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 s HSM)
az keyvault create \
    --name kv-pki-prod-hsm \
    --resource-group rg-pki \
    --location germanywestcentral \
    --sku premium

Managed HSM (FIPS 140-2 Nivo 3)

# Ustvarjanje Managed HSM
az keyvault create \
    --hsm-name hsm-pki-prod \
    --resource-group rg-pki \
    --location germanywestcentral \
    --administrators "user@example.com"
 
# Aktivacija HSM (zahteva 3 RSA ključe)
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

Upravljanje certifikatov

Uvoz certifikata

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

Pridobitev certifikata

// C# - Nalaganje certifikata iz Key Vault
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());
 
// Pridobitev certifikata kot Secret (vsebuje zasebni ključ)
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($"Ima zasebni ključ: {certificate.HasPrivateKey}");

Ustvarjanje certifikata s Key Vault CA

# Definicija politike certifikata
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
  }
}

Ključi za podpisovanje

Ustvarjanje ključa za podpisovanje

# EC ključ za podpise
az keyvault key create \
    --vault-name kv-pki-prod \
    --name signing-key \
    --kty EC \
    --curve P-384
 
# RSA ključ
az keyvault key create \
    --vault-name kv-pki-prod \
    --name rsa-signing-key \
    --kty RSA \
    --size 4096

Oddaljeno podpisovanje

// C# - Podpisovanje s ključem Azure Key Vault
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());
 
// Podpisovanje podatkov
byte[] dataToSign = Encoding.UTF8.GetBytes("Important document");
byte[] digest = SHA384.HashData(dataToSign);
 
SignResult signature = await cryptoClient.SignAsync(
    SignatureAlgorithm.ES384,
    digest);
 
Console.WriteLine($"Podpis: {Convert.ToBase64String(signature.Signature)}");
 
// Preverjanje podpisa
VerifyResult verified = await cryptoClient.VerifyAsync(
    SignatureAlgorithm.ES384,
    digest,
    signature.Signature);
 
Console.WriteLine($"Preverjeno: {verified.IsValid}");

Integracija App Service / AKS

App Service

# Key Vault referenca v App Settings
az webapp config appsettings set \
    --name myapp \
    --resource-group rg-app \
    --settings "Certificate=@Microsoft.KeyVault(VaultName=kv-pki-prod;SecretName=server-cert)"
 
# Aktivacija Managed Identity
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"

Nadzor

# Aktivacija diagnostike
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 poizvedba za operacije s certifikati:

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

Kontrolni seznam

# Kontrolna točka
—————–
1 Key Vault ustvarjen
2 Access Policies konfigurirane
3 Certifikati uvoženi
4 Managed Identity za aplikacije
5 Diagnostika aktivirana
6 Varnostno kopiranje konfigurirano

Povezana dokumentacija


« ← Integracija z oblakom | → AWS KMS »


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