Cloud allgemein

Data Encryption at Rest und In Transit: Praktischer Leitfaden mit KMS und TLS

Was du wirklich verschlüsseln musst, wie KMS richtig konfiguriert wird, wo TLS 1.3 Pflicht ist und welche DSGVO-Controls auditierbar sind — mit Terraform-Beispielen.

Harbinger Team3. April 20265 Min. LesezeitAktualisiert 14.5.2026
  • security
  • encryption
  • kms
  • tls
  • compliance
  • data-platform
  • dsgvo
Inhaltsverzeichnis18 Abschnitte

"Wir verschlüsseln unsere Daten" ist einer der missverstandensten Sätze in Cloud-Security. Er kann S3-Default-Encryption meinen (gut) oder eine selbstgebaute Crypto-Library (gruselig). Dieser Leitfaden gibt dir die Praktiker:innen-Sicht: was verschlüsseln, wie richtig, wo die Fallen liegen und wie du verifizierst.

TL;DR

  • Encryption schützt Storage und Wire — nicht kompromittierte Compute oder Identity.
  • Niemals eigenes Key-Material managen. KMS mit Customer-Managed Keys + automatischer Rotation.
  • Bucket-Key aktivieren, sonst trifft dich das KMS-Request-Quota.
  • TLS 1.3 überall, mTLS intern.
  • Column-Level Encryption für PII, die selbst vor DBAs versteckt sein muss.
  • DSGVO Art. 32 = KMS + Column-Level für personenbezogene Daten.

Threat Model

ThreatAt RestIn TransitBeide
Gestohlener S3-BucketJaJa
Kompromittierter NetzwerkpfadJaJa
Kompromittiertes Host-OS
Rogue DBA

Encryption ist kein Allheilmittel. Kombiniere mit IAM, VPC-Boundaries und Audit-Logging.

Encryption at Rest

AWS KMS: Envelope Encryption

KMS sieht deine Daten nie — es wrappt nur den Data Encryption Key (DEK). Deine App holt einen DEK, verschlüsselt damit die Daten und speichert DEK (encrypted) zusammen mit den Daten.

Terraform: KMS Key mit Rotation

resource "aws_kms_key" "data_platform" {
  description             = "Data platform encryption key"
  deletion_window_in_days = 30
  enable_key_rotation     = true
  multi_region            = false

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "AllowKeyAdministration"
        Effect    = "Allow"
        Principal = { AWS = "arn:aws:iam::${var.account_id}:role/DataPlatformAdmin" }
        Action    = ["kms:*"]
        Resource  = "*"
      },
      {
        Sid       = "AllowServiceUse"
        Effect    = "Allow"
        Principal = { Service = ["s3.amazonaws.com", "rds.amazonaws.com", "glue.amazonaws.com"] }
        Action    = ["kms:GenerateDataKey", "kms:Decrypt", "kms:DescribeKey"]
        Resource  = "*"
      }
    ]
  })

  tags = {
    Purpose  = "data-platform-encryption"
    Rotation = "annual-automatic"
  }
}

S3 Bucket Encryption mit Bucket-Key

resource "aws_s3_bucket_server_side_encryption_configuration" "data_lake" {
  bucket = aws_s3_bucket.data_lake["bronze"].id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = aws_kms_key.data_platform.arn
    }
    bucket_key_enabled = true  # Reduziert KMS-API-Kosten um 99 %
  }
}

resource "aws_s3_bucket_policy" "enforce_encryption" {
  bucket = aws_s3_bucket.data_lake["bronze"].id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Sid       = "DenyUnencryptedObjectUploads"
      Effect    = "Deny"
      Principal = "*"
      Action    = "s3:PutObject"
      Resource  = "${aws_s3_bucket.data_lake["bronze"].arn}/*"
      Condition = { StringNotEquals = { "s3:x-amz-server-side-encryption" = "aws:kms" } }
    }]
  })
}

RDS/Redshift Encryption

resource "aws_db_instance" "data_warehouse" {
  identifier              = "data-warehouse-${var.environment}"
  engine                  = "postgres"
  engine_version          = "15.4"
  instance_class          = "db.r6g.xlarge"
  storage_encrypted       = true
  kms_key_id              = aws_kms_key.data_platform.arn
  performance_insights_enabled    = true
  performance_insights_kms_key_id = aws_kms_key.data_platform.arn
  backup_retention_period = 30
}

Column-Level Encryption für PII

Für PII-Felder, die selbst vor DB-Admins verschlüsselt sein müssen.

encryption:
  enabled: true
  pii_columns:
    - email
    - phone_number
    - national_id
    - credit_card_number
  strategy: deterministic  # vs random (für Lookup-Joins)
  key_provider: aws_kms
  kms_key_id: "alias/data-platform-prod"
  cache_ttl_seconds: 300

Encryption in Transit

TLS 1.3 als Baseline

TLS 1.3 eliminiert die schwachen Cipher Suites aus 1.2. Erzwinge es überall.

openssl s_client -connect my-kafka-broker:9093 -tls1_3 2>/dev/null | grep -E "Protocol|Cipher"
# Erwartet:
# Protocol  : TLSv1.3
# Cipher    : TLS_AES_256_GCM_SHA384

Kafka TLS-Konfiguration

listeners=PLAINTEXT://localhost:9092,SSL://0.0.0.0:9093
ssl.keystore.location=/etc/kafka/ssl/kafka.server.keystore.jks
ssl.keystore.password=${KEYSTORE_PASSWORD}
ssl.truststore.location=/etc/kafka/ssl/kafka.server.truststore.jks
ssl.client.auth=required
ssl.enabled.protocols=TLSv1.3
ssl.cipher.suites=TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256

ALB + ACM für HTTP

resource "aws_lb_listener" "https" {
  load_balancer_arn = aws_lb.data_api.arn
  port              = "443"
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-2-2021-06"
  certificate_arn   = aws_acm_certificate_validation.api.certificate_arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.data_api.arn
  }
}

resource "aws_lb_listener" "http_redirect" {
  load_balancer_arn = aws_lb.data_api.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type = "redirect"
    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

Key Management Best Practices

Key TypeRotationMethode
KMS CMKJährlich, automatischenable_key_rotation
DEKsPro Job oder pro TagRe-wrap mit neuer CMK
TLS-Zertifikate90 Tage (Let's Encrypt) / Jährlich (ACM)Auto-Renew
DB-Master-Passwort90 TageSecrets Manager Rotation
API-Keys30–90 TageManuell + CI/CD

Secrets Manager Rotation

resource "aws_secretsmanager_secret" "db_password" {
  name                    = "data-platform/${var.environment}/db-master-password"
  kms_key_id              = aws_kms_key.data_platform.arn
  recovery_window_in_days = 7
}

resource "aws_secretsmanager_secret_rotation" "db_password" {
  secret_id           = aws_secretsmanager_secret.db_password.id
  rotation_lambda_arn = aws_lambda_function.db_password_rotator.arn
  rotation_rules { automatically_after_days = 90 }
}

Compliance-Mapping

AnforderungControlImplementierung
DSGVO Art. 32Verschlüsselung personenbezogener DatenKMS + Column-Level für PII
SOC 2 CC6.1Logical Access ControlsKMS Key Policies + IAM
PCI DSS 3.4Cardholder-Data-VerschlüsselungDeterministisches Column-Encryption
ISO 27001 A.10Kryptografische ControlsKey-Management-Policy

AWS Config Audits

resource "aws_config_config_rule" "s3_encryption" {
  name = "s3-bucket-server-side-encryption-enabled"
  source {
    owner             = "AWS"
    source_identifier = "S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED"
  }
}

resource "aws_config_config_rule" "kms_rotation" {
  name = "cmk-backing-key-rotation-enabled"
  source {
    owner             = "AWS"
    source_identifier = "CMK_BACKING_KEY_ROTATION_ENABLED"
  }
}

Häufige Fehler

  1. S3-Default ≠ Customer-Managed. AWS-managed Keys geben dir keine Usage-Logs oder Rotation-Control.
  2. Backups mit demselben Key wie Prod. Bei Key-Kompromiss sind beide weg.
  3. KMS-Request-Quotas ignorieren. Ohne Bucket-Key hittest du bei 10.000 req/s das Limit.
  4. TLS nur am LB terminieren. Backend-to-Backend muss auch verschlüsselt sein.
  5. Keys in App-Code. Niemals. Secrets Manager oder Env-Injection.

FAQ

Reicht S3-Default-Encryption für DSGVO? Für Encryption-at-Rest formal ja. Für Key-Rotation-Logs und Compliance-Nachweise brauchst du Customer-Managed CMKs.

eu-central-1 oder mehrere Regionen? DSGVO-konform reicht eu-central-1 (Frankfurt). Für Cross-Region DR multi-region KMS-Keys konfigurieren.

Wie oft KMS-Keys rotieren? KMS CMK jährlich automatisch reicht meist. DEKs öfter, z. B. pro Tag oder pro Job.

Was kostet KMS in eu-central-1? 1 $/Monat pro CMK + 0,03 $ pro 10.000 Requests. Ohne Bucket-Key explodiert das.

Stand: 14. Mai 2026.

H

Geschrieben von

Harbinger Team

Cloud-, Data- und AI-Engineer in DACH. Schreibt seit 2018 über infrastruktur­kritische Tech-Entscheidungen — keine Marketing- Folien, sondern echte Trade-offs aus Production-Workloads.

Hat dir das geholfen?

Jede Woche ein neuer Artikel über DACH-Cloud, Data und AI — direkt in dein Postfach. Kein Spam, kein Marketing-Sprech.

Kein Spam. 1-Klick-Abmeldung. Datenschutz bei Loops.so.