AWS KMS + CloudHSM

Cloud: Amazon Web Services
Livello HSM: FIPS 140-2 Livello 3 (CloudHSM) / Livello 2 (KMS)
Supporto PQ: Non ancora disponibile (stato 2024)

Integrazione di AWS Key Management Service e CloudHSM per operazioni PKI.


Architettura

flowchart TB subgraph AWS["☁️ AWS"] subgraph KMS["KMS"] K[Customer Managed Keys] AK[AWS Managed Keys] end subgraph CHSM["Cluster CloudHSM"] H1[HSM 1] H2[HSM 2] end subgraph ACM["Certificate Manager"] PC[Private CA] C[Certificates] end subgraph APPS["Applicazioni"] EC2[EC2] EKS[EKS] Lambda[Lambda] end end subgraph ONPREM["🏢 ON-PREM"] CA[Root CA] end CA -->|Cross-Sign| PC K --> APPS PC --> C --> APPS CHSM --> KMS style KMS fill:#fff3e0 style CHSM fill:#e8f5e9


Configurazione AWS KMS

Creazione CMK (Customer Managed Key)

# AWS CLI
aws kms create-key \
    --description "PKI Signing Key" \
    --key-usage SIGN_VERIFY \
    --key-spec ECC_NIST_P384 \
    --tags TagKey=Environment,TagValue=Production
 
# Creazione alias
aws kms create-alias \
    --alias-name alias/pki-signing-key \
    --target-key-id <key-id>
 
# Policy chiave
aws kms put-key-policy \
    --key-id <key-id> \
    --policy-name default \
    --policy file://key-policy.json
// key-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {"AWS": "arn:aws:iam::123456789012:root"},
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "Allow signing",
      "Effect": "Allow",
      "Principal": {"AWS": "arn:aws:iam::123456789012:role/PKI-Signing-Role"},
      "Action": ["kms:Sign", "kms:Verify", "kms:GetPublicKey"],
      "Resource": "*"
    }
  ]
}

Firma con KMS

// C# - Firma con AWS SDK
using Amazon.KeyManagementService;
using Amazon.KeyManagementService.Model;
 
var kmsClient = new AmazonKeyManagementServiceClient();
 
// Firma dati
byte[] dataToSign = Encoding.UTF8.GetBytes("Document content");
byte[] digest = SHA384.HashData(dataToSign);
 
var signRequest = new SignRequest
{
    KeyId = "alias/pki-signing-key",
    Message = new MemoryStream(digest),
    MessageType = MessageType.DIGEST,
    SigningAlgorithm = SigningAlgorithmSpec.ECDSA_SHA_384
};
 
SignResponse signResponse = await kmsClient.SignAsync(signRequest);
byte[] signature = signResponse.Signature.ToArray();
 
Console.WriteLine($"Firma: {Convert.ToBase64String(signature)}");
 
// Verifica
var verifyRequest = new VerifyRequest
{
    KeyId = "alias/pki-signing-key",
    Message = new MemoryStream(digest),
    MessageType = MessageType.DIGEST,
    Signature = new MemoryStream(signature),
    SigningAlgorithm = SigningAlgorithmSpec.ECDSA_SHA_384
};
 
VerifyResponse verifyResponse = await kmsClient.VerifyAsync(verifyRequest);
Console.WriteLine($"Valida: {verifyResponse.SignatureValid}");

AWS CloudHSM

Creazione cluster

# Creazione cluster CloudHSM
aws cloudhsmv2 create-cluster \
    --hsm-type hsm1.medium \
    --subnet-ids subnet-12345678 subnet-87654321
 
# Aggiunta HSM al cluster
aws cloudhsmv2 create-hsm \
    --cluster-id cluster-abc123 \
    --availability-zone eu-central-1a
 
# Inizializzazione cluster (richiede client CloudHSM)
/opt/cloudhsm/bin/cloudhsm_mgmt_util /opt/cloudhsm/etc/cloudhsm_mgmt_util.cfg
 
# In CMU:
# > loginHSM PRECO admin password
# > changePswd PRECO admin <new-password>

Generazione chiavi in CloudHSM

# Generazione chiavi PKCS#11 CloudHSM
pkcs11-tool --module /opt/cloudhsm/lib/libcloudhsm_pkcs11.so \
    --login --pin <CU-password> \
    --keypairgen --key-type EC:secp384r1 \
    --label "ca-signing-key" \
    --id 01

CloudHSM con KMS (Custom Key Store)

# Creazione Custom Key Store
aws kms create-custom-key-store \
    --custom-key-store-name cloudhsm-keystore \
    --cloud-hsm-cluster-id cluster-abc123 \
    --trust-anchor-certificate file://customerCA.crt \
    --key-store-password <kmsuser-password>
 
# Connessione Key Store
aws kms connect-custom-key-store \
    --custom-key-store-id cks-abc123
 
# Creazione chiave in Custom Key Store
aws kms create-key \
    --origin AWS_CLOUDHSM \
    --custom-key-store-id cks-abc123 \
    --key-spec ECC_NIST_P384 \
    --key-usage SIGN_VERIFY

AWS Certificate Manager Private CA

Creazione Private CA

# Configurazione CA
cat > ca-config.json << 'EOF'
{
  "KeyAlgorithm": "EC_secp384r1",
  "SigningAlgorithm": "SHA384WITHECDSA",
  "Subject": {
    "Country": "DE",
    "Organization": "Example Organization",
    "CommonName": "Example Private CA"
  }
}
EOF
 
# Creazione Private CA
aws acm-pca create-certificate-authority \
    --certificate-authority-configuration file://ca-config.json \
    --certificate-authority-type SUBORDINATE \
    --tags Key=Environment,Value=Production
 
# Generazione CSR
aws acm-pca get-certificate-authority-csr \
    --certificate-authority-arn <ca-arn> \
    --output text > ca.csr
 
# Firma CSR da Root-CA (esterna)
# ...
 
# Importazione certificato CA
aws acm-pca import-certificate-authority-certificate \
    --certificate-authority-arn <ca-arn> \
    --certificate file://ca-cert.pem \
    --certificate-chain file://chain.pem

Emissione certificato

# CSR per End-Entity
openssl req -new -key server.key -out server.csr \
    -subj "/CN=server.example.com"
 
# Emissione certificato
aws acm-pca issue-certificate \
    --certificate-authority-arn <ca-arn> \
    --csr fileb://server.csr \
    --signing-algorithm SHA384WITHECDSA \
    --validity Value=365,Type=DAYS \
    --template-arn arn:aws:acm-pca:::template/EndEntityCertificate/V1
 
# Recupero certificato
aws acm-pca get-certificate \
    --certificate-authority-arn <ca-arn> \
    --certificate-arn <cert-arn> \
    --output text > server.pem

Integrazione EKS

# IRSA (IAM Roles for Service Accounts)
# trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.eu-central-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringEquals": {
        "oidc.eks.eu-central-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:pki:cert-manager"
      }
    }
  }]
}
# ServiceAccount per cert-manager
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cert-manager
  namespace: pki
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/PKI-CertManager-Role
---
# ClusterIssuer per ACM Private CA
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: aws-pca-issuer
spec:
  acmPrivateCA:
    arn: arn:aws:acm-pca:eu-central-1:123456789012:certificate-authority/abc123
    region: eu-central-1

Integrazione Lambda

# lambda_function.py
import boto3
import base64
import hashlib
 
kms_client = boto3.client('kms')
 
def lambda_handler(event, context):
    data = event['data'].encode('utf-8')
    digest = hashlib.sha384(data).digest()
 
    # Firma
    sign_response = kms_client.sign(
        KeyId='alias/pki-signing-key',
        Message=digest,
        MessageType='DIGEST',
        SigningAlgorithm='ECDSA_SHA_384'
    )
 
    signature = base64.b64encode(sign_response['Signature']).decode()
 
    return {
        'statusCode': 200,
        'signature': signature
    }

Monitoraggio

# Allarme CloudWatch per KMS
aws cloudwatch put-metric-alarm \
    --alarm-name kms-signing-errors \
    --metric-name Errors \
    --namespace AWS/KMS \
    --statistic Sum \
    --period 300 \
    --threshold 1 \
    --comparison-operator GreaterThanOrEqualToThreshold \
    --dimensions Name=KeyId,Value=<key-id> \
    --evaluation-periods 1 \
    --alarm-actions arn:aws:sns:eu-central-1:123456789012:pki-alerts

Panoramica costi

Servizio Costo (ca.) Note
———-————-——
KMS CMK $1/mese + $0.03/10k richieste Standard
CloudHSM ~$1.50/ora (~$1100/mese) Per HSM
ACM Private CA $400/mese + $0.75/cert Per CA

Checklist

# Punto di verifica
——————-
1 Chiave KMS creata
2 Policy chiave configurata
3 Ruoli IAM creati
4 CloudTrail attivato
5 Allarmi CloudWatch
6 Strategia backup

Documentazione correlata


« ← Azure Key Vault | → HashiCorp Vault »


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

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