π AWS KMS Technical Documentation β
Complete implementation details for Hedera transaction signing with AWS KMS
Table of Contents β
- Overview
- How It Works
- Implementation Details
- Configuration
- Security Benefits
- Code Examples
- Troubleshooting
- References
Overview β
This implementation follows the Hedera AWS KMS Workshop pattern to securely sign Hedera transactions. Private keys never leave AWS infrastructure - only signatures are returned.
π‘οΈ Why AWS KMS for Blockchain? β
| Challenge | AWS KMS Solution |
|---|---|
| Private keys can be stolen from servers | Keys stored in tamper-proof HSM hardware |
| No way to prove who signed what | CloudTrail logs every signing operation |
| Key management is complex | Automatic rotation, backup, and access control |
| Compliance requirements | FIPS 140-2 Level 2, SOC 2, PCI DSS certified |
Implementation Status β
| Component | Status |
|---|---|
KMS Service (kms_service.py) | β Complete |
| Key verification on startup | β Working |
| Public key retrieval | β Working |
| Transaction signing | β Working |
| CloudTrail audit logging | β Automatic |
Architecture Summary β
βββββββββββββββββββ ββββββββββββββββ βββββββββββββββββββ
β LafaekStreet β β AWS KMS β β Hedera Network β
β Backend β β (HSM) β β β
β β β β β β
β 1. Create TX βββββββΆβ 2. Sign Hash βββββββΆβ 3. Verify & β
β & Hash it β β (secp256k1)β β Execute TX β
β (keccak256) ββββββββ β β β
β β β Return Sig β β β
βββββββββββββββββββ ββββββββββββββββ βββββββββββββββββββHow It Works β
Signing Flow β
1. Report Created
β
2. Hedera Service: Create transaction payload
β
3. KMS Service: Hash with keccak256
β
4. AWS KMS: Sign the hash (private key never leaves AWS)
β
5. KMS Service: Parse DER signature to raw format (r || s)
β
6. Hedera Service: Submit signed transaction
β
7. Hedera Network: Verify and record on blockchainKey Operations β
| Operation | Input | Output | Purpose |
|---|---|---|---|
keccak256() | Transaction bytes | 32-byte hash | Hedera requires keccak256 for ECDSA |
kms.sign() | Hash digest | DER signature | Hardware-backed signing |
parse_der() | DER signature (70-72 bytes) | Raw signature (64 bytes) | Convert to Hedera format |
Implementation Details β
KMS Service (app/services/kms_service.py) β
Key Methods β
sign_transaction(message: bytes) -> bytes
- Hashes transaction bytes with keccak256
- Sends digest to KMS for signing
- Parses DER-encoded signature to raw format (r || s)
- Returns 64-byte signature
get_hedera_public_key_hex() -> str
- Retrieves public key from KMS
- Removes ASN.1 DER prefix
- Returns hex string for Hedera account
create_hedera_signer() -> Callable
- Creates a signer function compatible with hiero-sdk-python
- Returns callable that signs transaction bytes
verify_kms_configuration() -> bool
- Verifies KMS key exists and is accessible
- Checks key spec is ECC_SECG_P256K1
- Validates key state is Enabled
Hedera Service Integration (app/services/hedera_service.py) β
On startup:
python
if settings.AWS_KMS_KEY_ID:
kms_service.verify_kms_configuration()
kms_signer = kms_service.create_hedera_signer()
self._kms_signer = kms_signerOn transaction:
python
# Create and freeze transaction
tx = TopicMessageSubmitTransaction()
tx.set_topic_id(topic_id)
tx.set_message(message)
tx.freeze_with(client)
# Sign with KMS
tx.sign(private_key) # KMS integration point
# Execute
receipt = tx.execute(client)Configuration β
Environment Variables β
bash
# AWS KMS Configuration
AWS_KMS_KEY_ID="arn:aws:kms:us-east-1:YOUR_ACCOUNT:key/YOUR_KEY_ID"
AWS_ACCESS_KEY_ID="AKIAXXXXXXXXXXXXXXXXX"
AWS_SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
AWS_REGION="us-east-1"Required IAM Permissions β
json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Sign",
"kms:GetPublicKey",
"kms:DescribeKey"
],
"Resource": "arn:aws:kms:us-east-1:YOUR_ACCOUNT:key/*"
}
]
}KMS Key Requirements β
| Property | Required Value |
|---|---|
| Key Spec | ECC_SECG_P256K1 |
| Key Usage | SIGN_VERIFY |
| Signing Algorithm | ECDSA_SHA_256 |
| State | Enabled |
Security Benefits β
Why KMS Over Environment Variables? β
| Aspect | .env File | AWS KMS |
|---|---|---|
| Key Storage | Plaintext file | Hardware Security Module |
| Key Export | Anyone can copy | Cannot be exported |
| Audit Trail | None | CloudTrail logs everything |
| Access Control | File permissions | IAM policies + MFA |
| Key Rotation | Manual | Automatic |
| Backup | Manual | Automatic multi-region |
Compliance Certifications β
- β FIPS 140-2 Level 2 - Hardware validation
- β SOC 2 - Security controls
- β PCI DSS - Payment card industry
- β HIPAA - Healthcare data
- β GDPR - Data protection
Security Features β
Private Key Never Exposed
- Generated and stored in tamper-resistant HSMs
- Cannot be exported or extracted
Complete Audit Trail
- All signing operations logged in CloudTrail
- Track who signed what and when
Fine-Grained Access Control
- IAM policies control key usage
- Multi-factor authentication support
Automatic Key Rotation
- Rotate keys without code changes
- Old signatures remain valid
Code Examples β
Signing Process (Python) β
python
from Crypto.Hash import keccak
from asn1crypto.core import Sequence
def sign_transaction(message: bytes) -> bytes:
# 1. Hash with keccak256 (required for Hedera ECDSA)
k = keccak.new(digest_bits=256)
k.update(message)
digest = k.digest()
# 2. Sign the digest with KMS
response = kms_client.sign(
KeyId=key_id,
Message=digest,
MessageType='DIGEST',
SigningAlgorithm='ECDSA_SHA_256'
)
# 3. Parse DER signature to raw format
# KMS returns: SEQUENCE { r INTEGER, s INTEGER }
# Hedera needs: r (32 bytes) || s (32 bytes)
seq = Sequence.load(response['Signature'])
r = seq[0].native.to_bytes(32, byteorder='big')
s = seq[1].native.to_bytes(32, byteorder='big')
return r + s # 64-byte raw signatureComparison with JavaScript Workshop β
JavaScript (Hedera Workshop):
javascript
const hash = keccak256(Buffer.from(message));
const signResponse = await kmsClient.send(new SignCommand({
KeyId: keyId,
Message: hash,
MessageType: "DIGEST",
SigningAlgorithm: "ECDSA_SHA_256",
}));
const decoded = EcdsaSigAsnParse.decode(signResponse.Signature, "der");Python (LafaekStreet):
python
digest = keccak256(message)
response = kms_client.sign(
KeyId=key_id,
Message=digest,
MessageType='DIGEST',
SigningAlgorithm='ECDSA_SHA_256'
)
seq = Sequence.load(response['Signature'])Log Output Examples β
Startup Logs β
================================================================================
π AWS KMS INTEGRATION ENABLED
================================================================================
β
KMS configuration verified successfully
- Key ID: f903385b-86db-478f-b7d0-84e45b657c9c
- Key Spec: ECC_SECG_P256K1
- Key State: Enabled
π KMS Public Key: 04edbf4926f65441dc403919dd884a8389b6ae2da400...
================================================================================Report Submission Logs β
================================================================================
π SUBMITTING REPORT TO HEDERA BLOCKCHAIN
Report Number: LS-260220-0001
π AWS KMS: ENABLED
================================================================================
π SIGNING HEDERA TRANSACTION WITH AWS KMS
π KMS: Hashed transaction with keccak256: a3f5e8d2...
π KMS: Signing transaction with key f903385b-...
β
KMS: Successfully signed transaction
================================================================================
β
TRANSACTION SUBMITTED SUCCESSFULLY
Transaction ID: 0.0.6255873@1708473892.123456789
π Signed with AWS KMS
π View on HashScan: https://hashscan.io/testnet/transaction/...
================================================================================Troubleshooting β
Common Errors β
| Error | Cause | Solution |
|---|---|---|
Module not found: Crypto | Missing pycryptodome | pip install pycryptodome==3.19.1 |
AWS_KMS_KEY_ID not configured | Missing env variable | Add AWS_KMS_KEY_ID to .env |
AccessDeniedException | Missing IAM permissions | Add kms:Sign, kms:GetPublicKey, kms:DescribeKey |
Invalid key spec | Wrong KMS key type | Create key with ECC_SECG_P256K1 spec |
KMS signing failed | Key disabled or wrong region | Check key state and AWS_REGION |
No KMS logs appearing | Feature disabled | Set FEATURE_BLOCKCHAIN=True |
Verification Steps β
Test KMS Configuration
bashpython test_kms_integration.pyCheck Startup Logs
bashgrep "KMS INTEGRATION" logs/app.logMonitor Signing Operations
bashtail -f logs/app.log | grep KMSVerify on HashScan
https://hashscan.io/testnet/transaction/{transaction_id}Check AWS CloudTrail
- Look for
kms:Signevents - Verify key usage patterns
- Look for
Dependencies β
| Package | Version | Purpose |
|---|---|---|
pycryptodome | 3.19.1 | keccak256 hashing |
ecdsa | 0.18.0 | Elliptic curve operations |
asn1crypto | 1.5.1 | DER signature parsing |
boto3 | (existing) | AWS SDK |
Install:
bash
pip install pycryptodome==3.19.1 ecdsa==0.18.0 asn1crypto==1.5.1References β
- Hedera AWS KMS Workshop - Original implementation reference
- AWS KMS Documentation - Official AWS docs
- Hedera Documentation - Hedera SDK reference
- secp256k1 Curve - Cryptographic curve details
- HashScan Explorer - Verify transactions
Related Documentation β
- Quick Start Guide - 5-minute setup
- Architecture Diagrams - Visual architecture
- Overview - Documentation index
β Implementation Complete and Production-Ready
