npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
NIST CSF 2.0
MITRE ATLAS
Overview
Hardware Security Modules (HSMs) are tamper-resistant physical devices that safeguard cryptographic keys and perform cryptographic operations in a hardened environment. Keys stored in an HSM never leave the device boundary, providing the highest level of key protection. This skill covers configuring HSMs using the PKCS#11 standard interface, including key generation, signing, encryption, and key management using both physical HSMs and SoftHSM2 for development.
When to Use
- When deploying or configuring configuring hsm for key storage capabilities in your environment
- When establishing security controls aligned to compliance requirements
- When building or improving security architecture for this domain
- When conducting security assessments that require this implementation
Prerequisites
- Familiarity with cryptography concepts and tools
- Access to a test or lab environment for safe execution
- Python 3.8+ with required dependencies installed
- Appropriate authorization for any testing activities
Objectives
- Configure SoftHSM2 as a development PKCS#11 provider
- Generate and manage keys inside the HSM via PKCS#11
- Perform cryptographic operations (sign, verify, encrypt, decrypt) using HSM-resident keys
- Implement HSM-backed certificate authority operations
- Configure key access policies and user authentication
- Interface with cloud HSM services (AWS CloudHSM, Azure)
Key Concepts
HSM Compliance Levels
| FIPS Level | Protection | Use Case |
|---|---|---|
| FIPS 140-2 Level 1 | Software only | Development |
| FIPS 140-2 Level 2 | Tamper-evident, role-based auth | General production |
| FIPS 140-2 Level 3 | Tamper-resistant, identity-based auth | Financial, government |
| FIPS 140-2 Level 4 | Physical tamper response | Military, classified |
PKCS#11 Architecture
Application --> PKCS#11 API --> HSM Provider --> Hardware HSM
|
(SoftHSM2 for dev)Key Objects in PKCS#11
| Object Type | Description | Operations |
|---|---|---|
| CKO_SECRET_KEY | Symmetric keys (AES) | Encrypt, Decrypt, Wrap |
| CKO_PUBLIC_KEY | Public keys (RSA, EC) | Verify, Encrypt, Wrap |
| CKO_PRIVATE_KEY | Private keys (RSA, EC) | Sign, Decrypt, Unwrap |
| CKO_CERTIFICATE | X.509 certificates | Storage, retrieval |
Security Considerations
- Never export private keys from HSM (use CKA_EXTRACTABLE=False)
- Use separate slots/partitions for different applications
- Implement multi-person key ceremony for CA root keys
- Enable audit logging for all HSM operations
- Implement HSM backup and disaster recovery
- Use strong PINs and enable SO (Security Officer) PIN
Validation Criteria
- SoftHSM2 initializes with token and user PIN
- AES key generates inside HSM
- RSA key pair generates inside HSM
- Encryption/decryption uses HSM-resident keys
- Signing/verification uses HSM-resident keys
- Keys cannot be exported (non-extractable)
- Key listing shows all HSM-stored objects
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 3
api-reference.md1.8 KB
HSM Key Storage — API Reference
Libraries
| Library | Install | Purpose |
|---|---|---|
| boto3 | pip install boto3 |
AWS CloudHSM and KMS API |
| python-pkcs11 | pip install python-pkcs11 |
PKCS#11 interface for HSM operations |
Key boto3 CloudHSMv2 Methods
| Method | Description |
|---|---|
describe_clusters() |
List CloudHSM clusters |
describe_backups() |
List cluster backups |
create_cluster(HsmType, SubnetIds) |
Create new cluster |
create_hsm(ClusterId, AvailabilityZone) |
Add HSM to cluster |
initialize_cluster(ClusterId, SignedCert, TrustAnchor) |
Initialize cluster |
Key boto3 KMS Methods (Custom Key Store)
| Method | Description |
|---|---|
create_custom_key_store() |
Create KMS custom key store backed by CloudHSM |
describe_key(KeyId) |
Get key metadata including CustomKeyStoreId |
create_key(Origin="AWS_CLOUDHSM", CustomKeyStoreId=) |
Create key in HSM |
PKCS#11 Operations
| Function | Description |
|---|---|
C_Initialize |
Initialize PKCS#11 library |
C_OpenSession |
Open session with HSM |
C_Login |
Authenticate with HSM PIN |
C_GenerateKeyPair |
Generate asymmetric key pair |
C_Sign / C_Verify |
Cryptographic signing operations |
HSM Types
| Type | Use Case |
|---|---|
| AWS CloudHSM | Cloud-native FIPS 140-2 Level 3 |
| Thales Luna | On-premises enterprise HSM |
| nCipher nShield | High-assurance code signing |
External References
standards.md1.6 KB
Standards and References - HSM for Key Storage
Primary Standards
PKCS#11 v3.0 (Cryptoki)
- URL: https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/pkcs11-base-v3.0.html
- Description: Standard API for cryptographic token interface
FIPS 140-2 / FIPS 140-3
- URL: https://csrc.nist.gov/publications/detail/fips/140/3/final
- Description: Security requirements for cryptographic modules
- CMVP: https://csrc.nist.gov/projects/cryptographic-module-validation-program
NIST SP 800-57 Part 1 Rev. 5
- URL: https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final
- Description: Key management recommendations (HSM storage for high-value keys)
HSM Products
SoftHSM2 (Development/Testing)
- URL: https://www.opendnssec.org/softhsm/
- GitHub: https://github.com/opendnssec/SoftHSMv2
- Description: Software-only PKCS#11 implementation for testing
AWS CloudHSM
- URL: https://docs.aws.amazon.com/cloudhsm/
- FIPS: 140-2 Level 3
- PKCS#11: https://docs.aws.amazon.com/cloudhsm/latest/userguide/pkcs11-library.html
Azure Dedicated HSM
- URL: https://docs.microsoft.com/en-us/azure/dedicated-hsm/
- FIPS: 140-2 Level 3 (Thales Luna)
Thales Luna HSM
- URL: https://cpl.thalesgroup.com/encryption/hardware-security-modules
- FIPS: 140-2 Level 3
Python Libraries
python-pkcs11
PyKCS11
workflows.md1.5 KB
Workflows - HSM for Key Storage
Workflow 1: SoftHSM2 Initialization
# Install SoftHSM2
# Ubuntu: apt install softhsm2
# macOS: brew install softhsm
# Initialize a token
softhsm2-util --init-token --slot 0 --label "MyToken" --pin 1234 --so-pin 5678
# List tokens
softhsm2-util --show-slotsWorkflow 2: Key Generation via PKCS#11
[Connect to HSM]
(open session, login with PIN)
|
[Generate Key]:
Symmetric: AES-256 (CKM_AES_KEY_GEN)
Asymmetric: RSA-4096 (CKM_RSA_PKCS_KEY_PAIR_GEN)
Asymmetric: EC P-256 (CKM_EC_KEY_PAIR_GEN)
|
[Set Key Attributes]:
CKA_EXTRACTABLE = False
CKA_SENSITIVE = True
CKA_TOKEN = True (persistent)
CKA_LABEL = "my-key-001"
|
[Key Stored in HSM]
(returns handle, not key material)Workflow 3: Cryptographic Operations
[Application Request]
|
[Open PKCS#11 Session]
|
[Find Key by Label/ID]
|
[Perform Operation on HSM]:
Sign: C_SignInit + C_Sign
Verify: C_VerifyInit + C_Verify
Encrypt: C_EncryptInit + C_Encrypt
Decrypt: C_DecryptInit + C_Decrypt
|
[Return Result to Application]
(key never leaves HSM)
|
[Close Session]Workflow 4: HSM Key Ceremony (Root CA)
[Prepare Air-Gapped HSM Station]
|
[Multi-Person Authentication]
(M-of-N key custodians present)
|
[Generate Root CA Key in HSM]
(CKA_EXTRACTABLE=False)
|
[Sign Root CA Certificate]
(self-signed, 20-year validity)
|
[Export Root CA Certificate]
(public certificate only)
|
[Secure HSM in Safe/Vault]
(offline until next signing ceremony)Scripts 2
agent.py4.8 KB
#!/usr/bin/env python3
"""HSM key storage management agent using PKCS#11 and AWS CloudHSM."""
import json
import sys
import argparse
from datetime import datetime
try:
import boto3
from botocore.exceptions import ClientError
except ImportError:
print("Install: pip install boto3")
sys.exit(1)
def list_cloudhsm_clusters(session):
"""List AWS CloudHSM clusters."""
client = session.client("cloudhsmv2")
clusters = []
response = client.describe_clusters()
for cluster in response.get("Clusters", []):
clusters.append({
"id": cluster["ClusterId"],
"state": cluster["State"],
"hsm_type": cluster["HsmType"],
"vpc_id": cluster.get("VpcId", ""),
"hsms": len(cluster.get("Hsms", [])),
"security_group": cluster.get("SecurityGroup", ""),
})
return clusters
def list_hsm_instances(session, cluster_id):
"""List HSM instances in a cluster."""
client = session.client("cloudhsmv2")
response = client.describe_clusters(Filters={"clusterIds": [cluster_id]})
hsms = []
for cluster in response.get("Clusters", []):
for hsm in cluster.get("Hsms", []):
hsms.append({
"hsm_id": hsm["HsmId"],
"az": hsm.get("AvailabilityZone", ""),
"ip": hsm.get("EniIp", ""),
"state": hsm.get("State", ""),
})
return hsms
def audit_kms_keys(session):
"""Audit KMS keys backed by CloudHSM custom key store."""
kms = session.client("kms")
custom_store_keys = []
paginator = kms.get_paginator("list_keys")
for page in paginator.paginate():
for key in page["Keys"]:
try:
desc = kms.describe_key(KeyId=key["KeyId"])
meta = desc["KeyMetadata"]
if meta.get("CustomKeyStoreId"):
custom_store_keys.append({
"key_id": meta["KeyId"],
"description": meta.get("Description", ""),
"key_state": meta["KeyState"],
"key_spec": meta.get("KeySpec", ""),
"custom_store_id": meta["CustomKeyStoreId"],
"origin": meta.get("Origin", ""),
})
except ClientError:
pass
return custom_store_keys
def check_cloudhsm_backup(session):
"""Check CloudHSM backup status."""
client = session.client("cloudhsmv2")
response = client.describe_backups()
backups = []
for backup in response.get("Backups", []):
backups.append({
"backup_id": backup["BackupId"],
"state": backup["BackupState"],
"cluster_id": backup.get("ClusterId", ""),
"create_time": str(backup.get("CreateTimestamp", "")),
})
return sorted(backups, key=lambda x: x["create_time"], reverse=True)
def run_audit(profile=None, region="us-east-1"):
"""Execute HSM key storage audit."""
session = boto3.Session(profile_name=profile, region_name=region)
print(f"\n{'='*60}")
print(f" HSM KEY STORAGE AUDIT")
print(f" Region: {region}")
print(f" Generated: {datetime.utcnow().isoformat()} UTC")
print(f"{'='*60}\n")
clusters = list_cloudhsm_clusters(session)
print(f"--- CLOUDHSM CLUSTERS ({len(clusters)}) ---")
for c in clusters:
print(f" {c['id']}: {c['state']} ({c['hsm_type']}, {c['hsms']} HSMs)")
for cluster in clusters:
hsms = list_hsm_instances(session, cluster["id"])
print(f"\n--- HSMs in {cluster['id']} ({len(hsms)}) ---")
for h in hsms:
print(f" {h['hsm_id']}: {h['state']} ({h['az']}, {h['ip']})")
keys = audit_kms_keys(session)
print(f"\n--- CUSTOM KEY STORE KEYS ({len(keys)}) ---")
for k in keys[:10]:
print(f" {k['key_id']}: {k['key_state']} ({k['key_spec']})")
backups = check_cloudhsm_backup(session)
print(f"\n--- BACKUPS ({len(backups)}) ---")
for b in backups[:5]:
print(f" {b['backup_id']}: {b['state']} ({b['create_time']})")
return {"clusters": clusters, "keys": keys, "backups": backups}
def main():
parser = argparse.ArgumentParser(description="HSM Key Storage Agent")
parser.add_argument("--profile", help="AWS CLI profile")
parser.add_argument("--region", default="us-east-1", help="AWS region")
parser.add_argument("--audit", action="store_true", help="Run full audit")
parser.add_argument("--output", help="Save report to JSON file")
args = parser.parse_args()
if args.audit:
report = run_audit(args.profile, args.region)
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
print(f"\n[+] Report saved to {args.output}")
else:
parser.print_help()
if __name__ == "__main__":
main()
process.py12.7 KB
#!/usr/bin/env python3
"""
HSM Key Storage Configuration Tool (PKCS#11)
Demonstrates HSM key management using PKCS#11 interface with SoftHSM2
for development and testing. Covers key generation, signing, encryption,
and key management operations.
Requirements:
pip install python-pkcs11 asn1crypto
# Also requires SoftHSM2 installed:
# Ubuntu: apt install softhsm2
# macOS: brew install softhsm
Usage:
python process.py init-token --label MyToken --pin 1234 --so-pin 5678
python process.py generate-aes --token MyToken --pin 1234 --label my-aes-key
python process.py generate-rsa --token MyToken --pin 1234 --label my-rsa-key
python process.py list-keys --token MyToken --pin 1234
python process.py sign --token MyToken --pin 1234 --key-label my-rsa-key --input data.txt
python process.py encrypt --token MyToken --pin 1234 --key-label my-aes-key --input data.txt
"""
import os
import sys
import json
import argparse
import logging
import subprocess
import platform
from pathlib import Path
from typing import Dict, List, Optional
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)
# Common SoftHSM2 library paths
SOFTHSM_PATHS = {
"linux": [
"/usr/lib/softhsm/libsofthsm2.so",
"/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so",
"/usr/local/lib/softhsm/libsofthsm2.so",
],
"darwin": [
"/usr/local/lib/softhsm/libsofthsm2.so",
"/opt/homebrew/lib/softhsm/libsofthsm2.so",
],
"win32": [
r"C:\SoftHSM2\lib\softhsm2-x64.dll",
r"C:\Program Files\SoftHSM2\lib\softhsm2-x64.dll",
],
}
def find_softhsm_lib() -> Optional[str]:
"""Find the SoftHSM2 library path."""
system = platform.system().lower()
if system == "windows":
paths = SOFTHSM_PATHS.get("win32", [])
elif system == "darwin":
paths = SOFTHSM_PATHS.get("darwin", [])
else:
paths = SOFTHSM_PATHS.get("linux", [])
for path in paths:
if Path(path).exists():
return path
env_path = os.environ.get("SOFTHSM2_LIB")
if env_path and Path(env_path).exists():
return env_path
return None
def init_token_via_cli(label: str, pin: str, so_pin: str) -> Dict:
"""Initialize a SoftHSM2 token using command-line tool."""
try:
result = subprocess.run(
["softhsm2-util", "--init-token", "--free",
"--label", label, "--pin", pin, "--so-pin", so_pin],
capture_output=True, text=True, timeout=30,
)
if result.returncode == 0:
logger.info(f"Token '{label}' initialized successfully")
slot_info = result.stdout.strip()
return {
"status": "success",
"label": label,
"message": slot_info or "Token initialized",
}
else:
return {"status": "error", "message": result.stderr.strip()}
except FileNotFoundError:
return {
"status": "error",
"message": "softhsm2-util not found. Install SoftHSM2 first.",
}
except Exception as e:
return {"status": "error", "message": str(e)}
def pkcs11_operations_demo(token_label: str, pin: str, lib_path: str) -> Dict:
"""
Demonstrate PKCS#11 operations using python-pkcs11.
This requires the python-pkcs11 package and SoftHSM2.
"""
try:
import pkcs11
from pkcs11 import KeyType, Attribute, ObjectClass, Mechanism
from pkcs11.util.rsa import encode_rsa_public_key
from pkcs11.util.ec import encode_named_curve_parameters
except ImportError:
return {
"status": "error",
"message": "python-pkcs11 not installed. Run: pip install python-pkcs11",
}
try:
lib = pkcs11.lib(lib_path)
token = lib.get_token(token_label=token_label)
except Exception as e:
return {"status": "error", "message": f"Cannot access token: {e}"}
results = {"operations": []}
with token.open(user_pin=pin, rw=True) as session:
# Generate AES-256 key
try:
aes_key = session.generate_key(
KeyType.AES, 256,
label="demo-aes-256",
store=True,
capabilities=pkcs11.defaults.DEFAULT_KEY_CAPABILITIES[KeyType.AES],
)
results["operations"].append({
"operation": "generate_aes_key",
"status": "success",
"label": "demo-aes-256",
"key_type": "AES-256",
})
except Exception as e:
results["operations"].append({
"operation": "generate_aes_key",
"status": "error",
"message": str(e),
})
# Generate RSA-2048 key pair
try:
pub_key, priv_key = session.generate_keypair(
KeyType.RSA, 2048,
label="demo-rsa-2048",
store=True,
)
results["operations"].append({
"operation": "generate_rsa_keypair",
"status": "success",
"label": "demo-rsa-2048",
"key_type": "RSA-2048",
})
except Exception as e:
results["operations"].append({
"operation": "generate_rsa_keypair",
"status": "error",
"message": str(e),
})
# AES Encryption/Decryption
try:
for key in session.get_objects({
Attribute.CLASS: ObjectClass.SECRET_KEY,
Attribute.LABEL: "demo-aes-256",
}):
iv = os.urandom(16)
plaintext = b"HSM encryption test data for PKCS#11"
padded = plaintext + (b"\x10" * (16 - len(plaintext) % 16))
ciphertext = key.encrypt(padded, mechanism=Mechanism.AES_CBC_PAD, mechanism_param=iv)
decrypted = key.decrypt(ciphertext, mechanism=Mechanism.AES_CBC_PAD, mechanism_param=iv)
results["operations"].append({
"operation": "aes_encrypt_decrypt",
"status": "success",
"match": decrypted.rstrip(b"\x10")[:len(plaintext)] == plaintext,
})
break
except Exception as e:
results["operations"].append({
"operation": "aes_encrypt_decrypt",
"status": "error",
"message": str(e),
})
# RSA Sign/Verify
try:
for key in session.get_objects({
Attribute.CLASS: ObjectClass.PRIVATE_KEY,
Attribute.LABEL: "demo-rsa-2048",
}):
data = b"Data to sign with HSM-resident RSA key"
signature = key.sign(data, mechanism=Mechanism.SHA256_RSA_PKCS)
results["operations"].append({
"operation": "rsa_sign",
"status": "success",
"signature_length": len(signature),
})
break
for key in session.get_objects({
Attribute.CLASS: ObjectClass.PUBLIC_KEY,
Attribute.LABEL: "demo-rsa-2048",
}):
valid = key.verify(data, signature, mechanism=Mechanism.SHA256_RSA_PKCS)
results["operations"].append({
"operation": "rsa_verify",
"status": "success",
"valid": True,
})
break
except Exception as e:
results["operations"].append({
"operation": "rsa_sign_verify",
"status": "error",
"message": str(e),
})
# List all objects
try:
objects = []
for obj in session.get_objects():
obj_info = {
"label": str(obj.get(Attribute.LABEL, "N/A")),
"class": str(obj.object_class),
}
objects.append(obj_info)
results["stored_objects"] = objects
except Exception as e:
results["stored_objects_error"] = str(e)
results["status"] = "success"
return results
def list_tokens(lib_path: str) -> Dict:
"""List all available PKCS#11 tokens."""
try:
import pkcs11
lib = pkcs11.lib(lib_path)
tokens = []
for slot in lib.get_slots(token_present=True):
token = slot.get_token()
tokens.append({
"slot_id": slot.slot_id,
"label": token.label.strip(),
"manufacturer": token.manufacturer_id.strip() if hasattr(token, 'manufacturer_id') else "N/A",
})
return {"status": "success", "tokens": tokens}
except ImportError:
return {"status": "error", "message": "python-pkcs11 not installed"}
except Exception as e:
return {"status": "error", "message": str(e)}
def generate_hsm_config() -> Dict:
"""Generate HSM configuration templates for different providers."""
configs = {
"softhsm2": {
"description": "SoftHSM2 (Development/Testing)",
"install": {
"ubuntu": "apt install softhsm2",
"macos": "brew install softhsm",
"windows": "Download from https://github.com/disig/SoftHSM2-for-Windows",
},
"config_file": "softhsm2.conf",
"config_content": "directories.tokendir = /var/lib/softhsm/tokens/\nobjectstore.backend = file\nlog.level = INFO\n",
"init_command": "softhsm2-util --init-token --free --label MyToken --pin 1234 --so-pin 5678",
},
"aws_cloudhsm": {
"description": "AWS CloudHSM",
"setup_steps": [
"Create CloudHSM cluster in AWS Console",
"Initialize the cluster",
"Install CloudHSM client on EC2 instance",
"Activate the cluster with crypto officer credentials",
"Install PKCS#11 library from AWS",
],
"pkcs11_lib": "/opt/cloudhsm/lib/libcloudhsm_pkcs11.so",
"config_file": "/opt/cloudhsm/etc/cloudhsm_client.cfg",
},
"azure_dedicated_hsm": {
"description": "Azure Dedicated HSM (Thales Luna)",
"setup_steps": [
"Provision Dedicated HSM via Azure Portal",
"Configure network connectivity (VNet peering)",
"Install Luna client on application server",
"Register client with HSM",
"Create partition for application",
],
"pkcs11_lib": "/usr/safenet/lunaclient/lib/libCryptoki2_64.so",
},
}
return configs
def main():
parser = argparse.ArgumentParser(description="HSM Key Storage Configuration Tool")
subparsers = parser.add_subparsers(dest="command")
init = subparsers.add_parser("init-token", help="Initialize HSM token")
init.add_argument("--label", required=True, help="Token label")
init.add_argument("--pin", required=True, help="User PIN")
init.add_argument("--so-pin", required=True, help="Security Officer PIN")
demo = subparsers.add_parser("demo", help="Run PKCS#11 operations demo")
demo.add_argument("--token", required=True, help="Token label")
demo.add_argument("--pin", required=True, help="User PIN")
demo.add_argument("--lib", help="PKCS#11 library path")
lst = subparsers.add_parser("list-tokens", help="List PKCS#11 tokens")
lst.add_argument("--lib", help="PKCS#11 library path")
subparsers.add_parser("config-templates", help="Show HSM configuration templates")
args = parser.parse_args()
if args.command == "init-token":
result = init_token_via_cli(args.label, args.pin, args.so_pin)
print(json.dumps(result, indent=2))
elif args.command == "demo":
lib_path = args.lib or find_softhsm_lib()
if not lib_path:
print(json.dumps({
"status": "error",
"message": "SoftHSM2 library not found. Set SOFTHSM2_LIB env var or use --lib.",
}, indent=2))
sys.exit(1)
result = pkcs11_operations_demo(args.token, args.pin, lib_path)
print(json.dumps(result, indent=2))
elif args.command == "list-tokens":
lib_path = args.lib or find_softhsm_lib()
if not lib_path:
print(json.dumps({"status": "error", "message": "SoftHSM2 library not found."}, indent=2))
sys.exit(1)
result = list_tokens(lib_path)
print(json.dumps(result, indent=2))
elif args.command == "config-templates":
configs = generate_hsm_config()
print(json.dumps(configs, indent=2))
else:
parser.print_help()
if __name__ == "__main__":
main()