Skip to content

HSM & KMS

HSM vs KMS

HSM KMS
Main Use Case Key storage Create & manage crypto keys
Tenancy Single-tenant HW Multi-tenant HW
Compliance FIPS 140-2 Level 3 FIPS 140-2 Level 2
Master Key Managed by customers only Managed by AWS KMS
Ciphers symm/asymm symm only
HA managed by customer managed by AWS
Regional Availability Select regions All regions (keys are regional)
Pricing Hourly By API calls and keys

Cloud HSM

Description
  • Key storage by making Hardware Security Modules (HSM) available in AWS
  • Dedicated hardware HSM appliances, not multi-tenant
  • FIPS 140-2 (level 3) compliant
Setup
  • Inside a VPC, in the region required
  • A private subnet for the HSM
  • An EC2 instance (control instance), in public subnet, with the cloudhsm_mgmt_util & key_mgmt_util tools
  • Recommended config = 2HSMs in HA

  • Setup process
    1. Create a VPC + Private & Public Subnet
    2. Create the HSM Cluster
    3. Verify HSMidentity
    4. Initialize the Cluster
    5. Launch a client instance && install the client
    6. Activate the cluster
    7. Setup users (HSM users authenticate with username + password)
    8. Generate keys
Tampering
  • If CloudHSM detects physical tampering —> destroys keys
  • 5 failed attempts to access an HSM partition as Crypto Office (CO) —> HSM appliance erases itself
  • 5 failed attempts to access an HSM with Crypto User (CU) creds —> user locked and must be unlocked by a CO

KMS

General Info

Description
  • Managed service to create and control encryption keys (AES-256)
  • Uses HSMs to protect the security of keys
  • Hardware shared across multi tenant
Location
  • KMS can be found under IAM (Encryption Keys)
  • IAM itself is global, but encryption keys are local to a specified region
  • Services using the key must be in the same region

CMK

Keys

Key Type Description
CUSTOMER MASTER KEY (CMK)
  • Used to encrypt/decrypt data
  • Provenance
    • AWS-managed CMK for each service that is integrated with AWS KMS
    • Customer-managed CMK that you generate by providing AWS with key material
  • Can be used
    • Inside KMS to encrypt/decrypt up to 4KB of data DIRECTLY
    • To encrypt generated DATA KEYS that are then used to encrypt/decrypt larger amounts of data outside KMS
  • CMKs can never leave KMS unencrypted (but Data Keys can)
  • You can schedule for deletion, it will take at least 7 days
  • Components
    • alias (name of the key)
    • creation date
    • description
    • key state (enabled/disabled/scheduled for deletion)
    • key material (either customer provided or AWS provided)
Data Keys
  • Used to encrypt data object within your app outside KMS
  • Call GenerateDataKey → returns PLAINTEXT version of the key & CIPHERTEXT that contains key encrypted under the specified CMK
  • To ENCRYPT from your app → use PLAINTEXT DATA KEY & store encrypted key alongside the encrypted data → remove plaintext key from memory ASAP
  • To DECRYPT → pass encrypted data key to decrypt function → KMS uses associated CMK to decrypt & retrieve plaintext data key → use plaintext key to decrypt data

Encryption

Envelope Encryption
  • Used to protect data
  • KMS creates data key → encrypts it under CMK → returns PLAINTEXT + ENCRYPTED DATA KEY
  • To ENCRYPT → use PLAINTEXT KEY & store unencrypted key with encrypted data
  • Retrieve PLAINTEXT DATA KEY ONLY if you have the encrypted data key & you have permission to use corresponding master key
Encryption Context
  • KMS crypto operations accept an OPTIONAL KEY/VALUE MAP of additional contextual info
  • Context must be the same for both encryption/decryption
  • Context is LOGGED

Setup/Import/Rotate CMK

Setup CMK
  • Create alias and description
  • Choose material option
  • Define Key Administrative Permissions: IAM users/roles that can administer (but not use) the key through the KMS API
  • Define Key Usage Permissions: IAM users/roles that can use the key to encrypt and decrypt data
Import Key material
  • You can import 256-bit symmetric keys
  • Wrapping key is the public key to use when generating a new key with openssl
  • Limitations
    • One key per CMK
      • when you import key material into a CMK, the CMK is permanently associated with that key material
      • you cannot import different key material into that CMK, and you cannot enable automatic key rotation for a CMK with imported key material
      • you can manually rotate a CMK with imported key material
    • Ciphertexts are not portable between CMKs
      • when you encrypt data under a KMS CMK, the ciphertext cannot be decrypted with any other CMK
      • this applies to all KMS CMKs, and remains true even when you import the same key material into a different CMK
  • Considerations
    • Availability and durability is different (allows to delete key material without waiting 7-30 days)
    • Secure key generation is up to you
    • No automatic rotation
    • Ciphertexts are not portable between CMKs
  • Process
    1. Create a CMK with no key material
    2. Download a public key (wrapping key) and import token
    3. Encrypt the key material
    4. Import the key material
    5. Cannot import a public key into KMS, you need to go through the generation process (key material origin)

Key rotation options

AWS Managed Keys
  • Rotates automatically every 3 years (you cannot rotate manually)
  • When the CMK is due for rotation, a new backing key is created and marked as the active key for all new requests
  • The old backing key remains available to decrypt any existing ciphertext files that were encrypted using the old key
  • AWS managed keys cannot be deleted
Customer managed keys
  • Once a year automatically (disabled by default)
  • On demand manually
    • create a new CMK, then change your applications or aliases to use the new CMK
    • you control the rotation frequency
  • Keys can be deleted
Customer managed CMK with imported key material
  • Automatic key rotation not available
  • The only option is to rotate keys manually

Access Options

Key Policy Condition
  • Policy Conditions can be used to specify a condition within a Key Policy or IAM Policy
    • If the key policy doesn't allow, then the request is denied regardless of identity policies
    • Principals allowed: accounts/users/roles/services (not groups) → Have to use IAM identity policies to manage access via groups
  • The condition must be true for the policy statement to take effect
  • kms:ViaService
    • condition key which can allow or deny access to CMK depending on which service originated the request
    • can be used in Key Policies and IAM policies which control access to KMS resources
    • the specified services must be integrated with KMS (S3, EBS, RDS, Systems Manager, SQS, Lambda)
KMS Grants
  • Grants are an alternative access control mechanism to a Key Policy
  • Features
    • Programmatically delegate the use of KMS CMKs to other AWS principals (e.g., a user in either your account or another account)
    • Temporary, granular permissions (encrypt, decrypt, re-encrypt, describekey)
    • Grants allow access, not deny
    • Use Key Policies for relatively static permissions and for explicit deny
Cross Account Access
  • Access to KMS CMKs is controlled using
    • The Key Policy: add the root user, not individual IAM users/roles
    • IAM Policies: define the allowed actions and the CMK ARN
  • If you want to enable another external account to encrypt/decrypt using your CMK, you need to enable cross account access
    • Enable access in the Key Policy for the account which owns the CMK
    • Enable access to KMS in the IAM Policy for the external account
KMS Grants - Commands
# Create a new key and make a note of the region you are working in
$ aws kms create-key

# Test encrypting plain text using the new key
$ aws kms encrypt --plaintext "hello" --key-id <key_arn>

# Create a new user called Dave and generate access key / secret access key
$ aws iam create-user --user-name dave
$aws iam create-access-key --user-name dave

# Run aws configure using Dave's credentials creating a CLI profile for him
$ aws configure --profile dave
$aws kms encrypt --plaintext "hello" --key-id <key_arn> --profile dave

# Create a grant for user called Dave
$ aws iam get-user --user-name dave
$ aws kms create-grant --key-id <key_arn> --grantee-principal <Dave_arn> --operations "Encrypt"

# Encrypt plain text as user Dave
$ aws kms encrypt --plaintext "hello" --key-id <key_arn> --grant-tokens <grant_token_from_previous_command> --profile dave

# Revoke the grant
$ aws kms list-grants --key-id <key_arn>
$ aws kms revoke-grant --key-id <key_arn> --grant-id <grant_id>
Enable cross account access
  • User in account 123 needs to use the CMK defined in account 456

  • Change the key policy for the CMK (in 456)
  • Add an IAM policy for the users/roles (in 123)
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowUseofKMSin456",
            "Effect": "Allow",
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt"
            ],
            "Resource": "arn:aws:kms:us-west-2:456:key/XXXXXX"
        }
    ]
}

Integrations

S3
  • If you encrypt with KMS
    • Even if you make the file public, people cannot access it cause they lack the key
    • Even if you are an S3 admin (unless you are full admin access Administrator), but don't have assigned rights to use the key to ecnrypt/decrypt ("key user"), then you won't be able to access the file
      • if you are SystemAdministrator you won't have permissions
  • If you encrypt with AES-256 (AWS S3 server-side encryption, AWS holds the keys)
    • If you make it public, it will be readable by everyone
EBS
  • We can use KMS to encrypt EBS volumes, but we cannot use KMS to generate a public/private key to log into EC2
  • We can import public keys into EC2 key pairs, but we cannot use EC2 key pairs to encrypt EBS volumes, we must use KMS or 3rd party apps
  • Provide EBS and tick on "Encrypt" (AWS managed)
    • once you provision a volume that is attached to an EC2 instance, and encrypt that volume with KMS, that volume is always gonna be linked to that key
  • Encrypt root device volume (where the OS run)
    • stop the EC2 instance
    • detach the volume from the EC2 instance
    • create a snapshot (AMI) - unencrypted
    • create a new AMI image from the snapshot, encrypting it while copying: actions > copy AMI > thick encryption (Encrypt target EBS snapshots) > specify CMK
    • you can change encryption keys on EBS volumes by initiating the copy command
      • you need to be in the same region where keys are stored
      • you need to be root user (or have permissions)
      • if you copy to different region you'll have different keys