Automated discovery of quantum-vulnerable cryptography across cloud infrastructure
Build a comprehensive cryptographic asset inventory as required by OMB M-23-02 and CISA guidelines. These free scripts automatically discover RSA, ECC, and DH usage across Azure and AWS.
Educational Purpose Only: All code samples and scripts provided on this page are for educational and illustrative purposes. They are NOT production-ready and have NOT been thoroughly tested in all environments.
Recommendation: Treat these examples as starting points for learning and development. Adapt, test, and validate according to your specific requirements and security standards.
# Clone and setup git clone https://github.com/spindynamics/pqc-tools.git cd pqc-tools ./setup.sh source venv/bin/activate # Run inventory scan (Azure) python azure/inventory_scanner.py \ --subscription-id YOUR_SUBSCRIPTION_ID \ --output inventory/azure-crypto-inventory.json # Run inventory scan (AWS) python aws/inventory_scanner.py \ --region us-east-1 \ --output inventory/aws-crypto-inventory.json
Discovers all keys, secrets, and certificates in Azure Key Vaults
python azure/keyvault_inventory.py \ --subscription-id YOUR_SUBSCRIPTION_ID \ --output inventory/azure-keyvault-inventory.json \ --include-properties \ --check-expiration
Discovers: Key types (RSA/EC/oct), key sizes, creation dates, expiration dates, enabled/disabled status
#!/usr/bin/env python3
"""Azure Key Vault Cryptographic Inventory Scanner"""
import azure.identity
import azure.keyvault.keys
import azure.keyvault.secrets
import azure.keyvault.certificates
from azure.mgmt.keyvault import KeyVaultManagementClient
import json
from datetime import datetime
def scan_azure_keyvaults(subscription_id):
"""Scan all Key Vaults in subscription"""
credential = azure.identity.DefaultAzureCredential()
kv_mgmt_client = KeyVaultManagementClient(credential, subscription_id)
inventory = {
"scan_date": datetime.now().isoformat(),
"subscription_id": subscription_id,
"vaults": []
}
# List all key vaults
vaults = kv_mgmt_client.vaults.list()
for vault in vaults:
vault_url = f"https://{vault.name}.vault.azure.net"
print(f"Scanning vault: {vault.name}")
vault_data = {
"name": vault.name,
"resource_group": vault.id.split('/')[4],
"location": vault.location,
"keys": [],
"certificates": [],
"vulnerable_count": 0
}
try:
# Scan keys
key_client = azure.keyvault.keys.KeyClient(vault_url, credential)
for key_props in key_client.list_properties_of_keys():
key = key_client.get_key(key_props.name)
key_info = {
"name": key.name,
"type": key.key.kty,
"enabled": key.properties.enabled,
"created": key.properties.created_on.isoformat() if key.properties.created_on else None,
"expires": key.properties.expires_on.isoformat() if key.properties.expires_on else None,
"quantum_vulnerable": False
}
# Check if quantum-vulnerable
if key.key.kty in ["RSA", "EC", "RSA-HSM", "EC-HSM"]:
key_info["quantum_vulnerable"] = True
vault_data["vulnerable_count"] += 1
if key.key.kty.startswith("RSA"):
key_info["key_size"] = key.key.n.bit_length() if key.key.n else None
elif key.key.kty.startswith("EC"):
key_info["curve"] = key.key.crv.value if key.key.crv else None
vault_data["keys"].append(key_info)
# Scan certificates
cert_client = azure.keyvault.certificates.CertificateClient(vault_url, credential)
for cert_props in cert_client.list_properties_of_certificates():
cert = cert_client.get_certificate(cert_props.name)
cert_info = {
"name": cert.name,
"subject": str(cert.properties.subject) if cert.properties.subject else None,
"thumbprint": cert.properties.thumbprint.hex() if cert.properties.thumbprint else None,
"enabled": cert.properties.enabled,
"expires": cert.properties.expires_on.isoformat() if cert.properties.expires_on else None,
"quantum_vulnerable": True # Most X.509 certs use RSA/ECDSA
}
vault_data["certificates"].append(cert_info)
vault_data["vulnerable_count"] += 1
except Exception as e:
vault_data["error"] = str(e)
print(f" Error scanning {vault.name}: {e}")
inventory["vaults"].append(vault_data)
# Summary
total_vulnerable = sum(v["vulnerable_count"] for v in inventory["vaults"])
inventory["summary"] = {
"total_vaults": len(inventory["vaults"]),
"total_vulnerable_assets": total_vulnerable
}
return inventory
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
print("Usage: python keyvault_inventory.py SUBSCRIPTION_ID")
sys.exit(1)
subscription_id = sys.argv[1]
results = scan_azure_keyvaults(subscription_id)
# Save to file
with open("azure-keyvault-inventory.json", "w") as f:
json.dump(results, f, indent=2)
print(f"\\nInventory complete!")
print(f"Total vaults scanned: {results['summary']['total_vaults']}")
print(f"Quantum-vulnerable assets: {results['summary']['total_vulnerable_assets']}")
Scans AWS KMS for RSA and ECC keys across all regions
python aws/kms_inventory.py \ --profile default \ --all-regions \ --output inventory/aws-kms-inventory.json
#!/usr/bin/env python3
"""AWS KMS Cryptographic Inventory Scanner"""
import boto3
import json
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor, as_completed
def scan_kms_region(region_name):
"""Scan KMS keys in a single region"""
print(f"Scanning region: {region_name}")
kms = boto3.client('kms', region_name=region_name)
vulnerable_keys = []
try:
# List all KMS keys
paginator = kms.get_paginator('list_keys')
for page in paginator.paginate():
for key in page['Keys']:
key_id = key['KeyId']
try:
# Get key metadata
metadata = kms.describe_key(KeyId=key_id)['KeyMetadata']
key_spec = metadata.get('KeySpec', 'SYMMETRIC_DEFAULT')
key_usage = metadata.get('KeyUsage', 'ENCRYPT_DECRYPT')
# Check if quantum-vulnerable
vulnerable_specs = [
'RSA_2048', 'RSA_3072', 'RSA_4096',
'ECC_NIST_P256', 'ECC_NIST_P384', 'ECC_NIST_P521',
'ECC_SECG_P256K1'
]
if key_spec in vulnerable_specs:
key_info = {
"KeyId": key_id,
"KeyArn": metadata['Arn'],
"KeySpec": key_spec,
"KeyUsage": key_usage,
"KeyState": metadata['KeyState'],
"CreationDate": metadata['CreationDate'].isoformat(),
"Enabled": metadata['Enabled'],
"Description": metadata.get('Description', ''),
"Region": region_name
}
# Get key tags
try:
tags_response = kms.list_resource_tags(KeyId=key_id)
key_info["Tags"] = {tag['TagKey']: tag['TagValue']
for tag in tags_response.get('Tags', [])}
except:
key_info["Tags"] = {}
vulnerable_keys.append(key_info)
except Exception as e:
print(f" Error describing key {key_id}: {e}")
except Exception as e:
print(f" Error scanning region {region_name}: {e}")
return {"region": region_name, "error": str(e), "keys": []}
return {"region": region_name, "keys": vulnerable_keys, "count": len(vulnerable_keys)}
def scan_all_aws_kms():
"""Scan all AWS regions for KMS keys"""
ec2 = boto3.client('ec2', region_name='us-east-1')
regions = [r['RegionName'] for r in ec2.describe_regions()['Regions']]
inventory = {
"scan_date": datetime.now().isoformat(),
"regions": [],
"total_vulnerable_keys": 0
}
# Scan regions in parallel
with ThreadPoolExecutor(max_workers=5) as executor:
future_to_region = {executor.submit(scan_kms_region, region): region
for region in regions}
for future in as_completed(future_to_region):
region_data = future.result()
inventory["regions"].append(region_data)
inventory["total_vulnerable_keys"] += region_data.get("count", 0)
return inventory
if __name__ == "__main__":
results = scan_all_aws_kms()
# Save to file
with open("aws-kms-inventory.json", "w") as f:
json.dump(results, f, indent=2, default=str)
print(f"\\n=== AWS KMS Inventory Complete ===")
print(f"Regions scanned: {len(results['regions'])}")
print(f"Quantum-vulnerable keys found: {results['total_vulnerable_keys']}")
# Summary by region
print("\\nBy Region:")
for region_data in sorted(results['regions'], key=lambda x: x.get('count', 0), reverse=True):
if region_data.get('count', 0) > 0:
print(f" {region_data['region']}: {region_data['count']} vulnerable keys")
Discovers all SSL/TLS certificates and analyzes signature algorithms
# Azure App Service Certificates python azure/certificate_inventory.py \ --subscription-id YOUR_SUBSCRIPTION_ID \ --output inventory/azure-certificates.json # AWS Certificate Manager (ACM) python aws/acm_inventory.py \ --all-regions \ --output inventory/aws-acm-certificates.json # AWS IAM Server Certificates python aws/iam_certificate_inventory.py \ --output inventory/aws-iam-certificates.json
Output includes: Subject, Issuer, Serial number, Signature algorithm (RSA/ECDSA), Key size, Expiration date, SANs
Discovers all TLS endpoints and cipher suites
# Scan from endpoint list python shared/tls_endpoint_scanner.py \ --endpoints-file endpoints.txt \ --output inventory/tls-endpoints.json # Auto-discover from Azure Load Balancers python azure/lb_endpoint_discovery.py \ --subscription-id YOUR_SUBSCRIPTION_ID \ --scan-tls \ --output inventory/azure-lb-tls.json # Auto-discover from AWS ELB/ALB python aws/elb_endpoint_discovery.py \ --all-regions \ --scan-tls \ --output inventory/aws-elb-tls.json
Inventories encryption-at-rest configurations for databases
# Azure SQL Database TDE python azure/sql_encryption_inventory.py \ --subscription-id YOUR_SUBSCRIPTION_ID \ --output inventory/azure-sql-encryption.json # AWS RDS Encryption python aws/rds_encryption_inventory.py \ --all-regions \ --output inventory/aws-rds-encryption.json # AWS DynamoDB Encryption python aws/dynamodb_encryption_inventory.py \ --all-regions \ --output inventory/aws-dynamodb-encryption.json
Checks encryption methods for cloud storage
# Azure Storage Accounts python azure/storage_encryption_inventory.py \ --subscription-id YOUR_SUBSCRIPTION_ID \ --output inventory/azure-storage-encryption.json # AWS S3 Bucket Encryption python aws/s3_encryption_inventory.py \ --output inventory/aws-s3-encryption.json
Combines all inventory scans into OMB M-23-02 compliant report
python shared/consolidate_inventory.py \ --input-dir inventory/ \ --output reports/crypto-inventory-master.json \ --format json,csv,html # This generates: # - crypto-inventory-master.json (machine-readable) # - crypto-inventory-master.csv (spreadsheet) # - crypto-inventory-master.html (interactive report)
#!/bin/bash
# complete-inventory.sh - Build comprehensive crypto inventory
source venv/bin/activate
mkdir -p inventory reports
echo "=== Starting Cryptographic Inventory ==="
# Azure Inventory
if [ ! -z "$AZURE_SUBSCRIPTION_ID" ]; then
echo "\\n1. Azure Key Vault inventory..."
python azure/keyvault_inventory.py \
--subscription-id $AZURE_SUBSCRIPTION_ID \
--output inventory/azure-keyvault.json
echo "2. Azure Certificate inventory..."
python azure/certificate_inventory.py \
--subscription-id $AZURE_SUBSCRIPTION_ID \
--output inventory/azure-certificates.json
echo "3. Azure SQL encryption..."
python azure/sql_encryption_inventory.py \
--subscription-id $AZURE_SUBSCRIPTION_ID \
--output inventory/azure-sql.json
echo "4. Azure Storage encryption..."
python azure/storage_encryption_inventory.py \
--subscription-id $AZURE_SUBSCRIPTION_ID \
--output inventory/azure-storage.json
fi
# AWS Inventory
if aws sts get-caller-identity &> /dev/null; then
echo "\\n5. AWS KMS inventory..."
python aws/kms_inventory.py \
--all-regions \
--output inventory/aws-kms.json
echo "6. AWS ACM certificates..."
python aws/acm_inventory.py \
--all-regions \
--output inventory/aws-acm.json
echo "7. AWS RDS encryption..."
python aws/rds_encryption_inventory.py \
--all-regions \
--output inventory/aws-rds.json
echo "8. AWS S3 encryption..."
python aws/s3_encryption_inventory.py \
--output inventory/aws-s3.json
fi
# Network Scanning
if [ -f "endpoints.txt" ]; then
echo "\\n9. TLS endpoint scanning..."
python shared/tls_endpoint_scanner.py \
--endpoints-file endpoints.txt \
--output inventory/tls-endpoints.json
fi
# Consolidate
echo "\\n10. Generating consolidated report..."
python shared/consolidate_inventory.py \
--input-dir inventory/ \
--output reports/crypto-inventory-master \
--format json,csv,html
echo "\\n=== Inventory Complete ==="
echo "Reports available in: reports/"
echo " - crypto-inventory-master.json"
echo " - crypto-inventory-master.csv"
echo " - crypto-inventory-master.html"
echo ""
echo "Summary:"
python shared/inventory_summary.py reports/crypto-inventory-master.json
{
"scan_date": "2024-11-06T14:30:00Z",
"inventory_version": "1.0",
"cloud_providers": ["azure", "aws"],
"summary": {
"total_assets": 1247,
"quantum_vulnerable": 856,
"by_type": {
"keys": 342,
"certificates": 189,
"tls_endpoints": 284,
"database_encryption": 41
},
"by_algorithm": {
"RSA-2048": 412,
"RSA-4096": 178,
"ECDSA-P256": 156,
"ECDSA-P384": 110
}
},
"assets": [
{
"asset_id": "azure-kv-prod-app-signing-key",
"asset_type": "key",
"cloud_provider": "azure",
"resource_id": "/subscriptions/.../keys/app-signing-key",
"name": "app-signing-key",
"algorithm": "RSA",
"key_size": 2048,
"created_date": "2021-03-15",
"expiration_date": "2025-03-15",
"quantum_vulnerable": true,
"risk_level": "HIGH",
"data_classification": "confidential",
"usage": "code-signing",
"recommended_migration": "ML-DSA-65 or hybrid RSA+ML-DSA",
"priority": 1
}
],
"compliance": {
"omb_m23_02": {
"inventory_maintained": true,
"last_updated": "2024-11-06",
"migration_plan_exists": false
},
"cnsa_2_0": {
"compliant_assets": 391,
"non_compliant_assets": 856,
"target_date": "2030-01-01"
}
}
}
Spreadsheet with columns:
Automate inventory updates as part of your deployment pipeline:
name: PQC Crypto Inventory Scan
on:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday
workflow_dispatch:
jobs:
inventory:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install -r requirements.txt
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Configure AWS
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Run inventory scan
run: |
./complete-inventory.sh
- name: Upload results
uses: actions/upload-artifact@v3
with:
name: crypto-inventory
path: reports/
- name: Check for new vulnerabilities
run: |
python shared/inventory_diff.py \
--baseline inventory/baseline.json \
--current reports/crypto-inventory-master.json \
--fail-on-new-high-risk
100% Free & Open Source Educational Resource
SpinDynamics.io - Making Quantum Security Accessible to All
← Return to Homepage