Azure Key Vault

Cloud: Microsoft Azure
Livello HSM: FIPS 140-2 Livello 2 (Standard) / Livello 3 (Managed HSM)
Supporto PQ: Non ancora disponibile (stato 2024)

Integrazione di Azure Key Vault per la gestione di certificati e chiavi.


Architettura

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["Applicazioni"] A1[App Service] A2[AKS] A3[Functions] end end subgraph ONPREM["🏢 ON-PREM"] CA[CA Interna] end CA -->|Import| C K --> A1 & A2 & A3 C --> A1 & A2 & A3 H -->|Premium| K style KV fill:#e3f2fd style HSM fill:#e8f5e9


Configurazione

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

Managed HSM (FIPS 140-2 Livello 3)

# Creazione Managed HSM
az keyvault create \
    --hsm-name hsm-pki-prod \
    --resource-group rg-pki \
    --location germanywestcentral \
    --administrators "user@example.com"
 
# Attivazione HSM (richiede 3 chiavi RSA)
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

Gestione certificati

Importazione certificato

# Importazione certificato PFX
az keyvault certificate import \
    --vault-name kv-pki-prod \
    --name server-cert \
    --file server.pfx \
    --password "pfx-password"
// C# - Importazione certificato
using Azure.Identity;
using Azure.Security.KeyVault.Certificates;
 
var client = new CertificateClient(
    new Uri("https://kv-pki-prod.vault.azure.net/"),
    new DefaultAzureCredential());
 
// Importazione 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($"Importato: {cert.Name}, Thumbprint: {cert.Properties.X509Thumbprint}");

Recupero certificato

// C# - Caricamento certificato da 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());
 
// Recupero certificato come Secret (contiene chiave privata)
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}");

Creazione certificato con CA Key Vault

# Definizione policy certificato
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
  }
}

Chiavi per firma

Creazione chiave di firma

# Chiave EC per firme
az keyvault key create \
    --vault-name kv-pki-prod \
    --name signing-key \
    --kty EC \
    --curve P-384
 
# Chiave RSA
az keyvault key create \
    --vault-name kv-pki-prod \
    --name rsa-signing-key \
    --kty RSA \
    --size 4096

Firma remota

// C# - Firma con chiave 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());
 
// Firma dati
byte[] dataToSign = Encoding.UTF8.GetBytes("Important document");
byte[] digest = SHA384.HashData(dataToSign);
 
SignResult signature = await cryptoClient.SignAsync(
    SignatureAlgorithm.ES384,
    digest);
 
Console.WriteLine($"Firma: {Convert.ToBase64String(signature.Signature)}");
 
// Verifica firma
VerifyResult verified = await cryptoClient.VerifyAsync(
    SignatureAlgorithm.ES384,
    digest,
    signature.Signature);
 
Console.WriteLine($"Verificata: {verified.IsValid}");

Integrazione App Service / AKS

App Service

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

Monitoraggio

# Attivazione diagnostica
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>

Query KQL per operazioni sui certificati:

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

Checklist

# Punto di verifica
——————-
1 Key Vault creato
2 Access Policy configurate
3 Certificati importati
4 Managed Identity per app
5 Diagnostica attivata
6 Backup configurato

Documentazione correlata


« ← Integrazione Cloud | → AWS KMS »


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

Zuletzt geändert: il 30/01/2026 alle 01:26