👋 Introduction
On September 9, 2025, Amazon CloudFront added support for ECDSA (Elliptic Curve Digital Signature Algorithm) keys in signed URLs. Previously limited to RSA-2048, CloudFront now supports ECDSA P-256 (prime256v1), enabling significantly faster signature generation and shorter URLs.
This article demonstrates implementing ECDSA signed URLs and compares performance with traditional RSA keys.
https://aws.amazon.com/about-aws/whats-new/2025/09/amazon-cloudfront-ecdsa-signed-urls/
📌 What's New
Key Changes
- CloudFront signed URLs now support ECDSA (P-256) alongside RSA
- Faster signature generation with lower CPU usage
- Smaller signature size resulting in shorter URLs
- Same security level as RSA with better performance
Expected Benefits
- Performance: Faster signature generation for high-volume scenarios
- Efficiency: Reduced CPU usage, ideal for resource-constrained environments
- URL Length: Shorter URLs for SMS, QR codes, and other length-sensitive use cases
Implementation Guide
1. Generate Key Pairs
# Generate ECDSA P-256 private key openssl ecparam -name prime256v1 -genkey -noout -out ecdsa-private.pem # Generate public key openssl ec -in ecdsa-private.pem -pubout -out ecdsa-public.pem # For comparison, generate RSA keys openssl genrsa -out rsa-private.pem 2048 openssl rsa -pubout -in rsa-private.pem -out rsa-public.pem
2. Register Public Keys with CloudFront
# Register ECDSA public key ECDSA_KEY_CONTENT=$(cat ecdsa-public.pem) ECDSA_KEY_RESPONSE=$(aws cloudfront create-public-key \ --public-key-config \ Name="ecdsa-signing-key",CallerReference="$(date +%s)",EncodedKey="$ECDSA_KEY_CONTENT",Comment="ECDSA P-256 key for signed URLs") ECDSA_KEY_ID=$(echo $ECDSA_KEY_RESPONSE | jq -r '.PublicKey.Id') echo "ECDSA Key ID: $ECDSA_KEY_ID"
3. Create Key Groups
# Create ECDSA key group ECDSA_KEY_GROUP_RESPONSE=$(aws cloudfront create-key-group \ --key-group-config \ Name="ecdsa-key-group",Items="$ECDSA_KEY_ID",Comment="ECDSA key group") ECDSA_KEY_GROUP_ID=$(echo $ECDSA_KEY_GROUP_RESPONSE | jq -r '.KeyGroup.Id')
4. Configure CloudFront Distribution
⚠️ Important: Update your CloudFront distribution behavior settings.
- Go to your distribution's "Behaviors" tab
- Edit the relevant behavior
- Set "Restrict viewer access" to "Yes"
- Set "Trusted authorization type" to "Trusted key groups"
- Select your created key group
5. Generate Signed URLs
AWS CLI Limitation
⚠️ Important: As of September 9, 2025, the AWS CLI's cloudfront sign command doesn't support ECDSA keys and throws an error saying it's not an RSA key.
# aws --version # aws-cli/2.29.0 # This will fail with ECDSA keys aws cloudfront sign --url https://example.com/file.jpg \ --key-pair-id $ECDSA_KEY_ID \ --private-key file://ecdsa-private.pem \ --date-less-than "2025-09-10T12:09:03Z" # Error: RSA private key not found in PEM.
Python Implementation
Here's a working Python implementation for ECDSA signed URLs.
# ecdsa_signer.py import sys import time from botocore.signers import CloudFrontSigner from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.serialization import load_pem_private_key from cryptography.hazmat.backends import default_backend import os from datetime import datetime def ecdsa_signer(message): with open("ecdsa-private.pem", "rb") as key_file: private_key = load_pem_private_key( key_file.read(), password=None, backend=default_backend() ) return private_key.sign(message, ec.ECDSA(hashes.SHA1())) def generate_signed_url(url, key_pair_id, date_less_than): start_time = time.time() cf_signer = CloudFrontSigner(key_pair_id, ecdsa_signer) signed_url = cf_signer.generate_presigned_url( url, date_less_than=datetime.fromisoformat(date_less_than.replace("Z", "+00:00")), ) processing_time_ms = (time.time() - start_time) * 1000 print(f"ECDSA processing time: {processing_time_ms:.2f}ms", file=sys.stderr) return signed_url if __name__ == "__main__": url = sys.argv[1] if len(sys.argv) > 1 else "https://example.com/file.jpg" expiry_time = sys.argv[2] if len(sys.argv) > 2 else "2025-09-10T12:09:03Z" key_pair_id = os.environ.get("ECDSA_KEY_ID") signed_url = generate_signed_url(url, key_pair_id, expiry_time) print(signed_url)
Performance Comparison
I ran performance tests comparing RSA and ECDSA signature generation.
Results Summary
Test Runs | RSA Average | ECDSA Average | Improvement | RSA StdDev | ECDSA StdDev |
---|---|---|---|---|---|
1 | 36.47ms | 3.04ms | 91.7% | 0.00ms | 0.00ms |
10 | 35.93ms | 3.00ms | 91.6% | 2.54ms | 0.31ms |
20 | 33.54ms | 2.60ms | 92.2% | 0.98ms | 0.21ms |
100 | 34.39ms | 2.91ms | 91.5% | 1.33ms | 0.58ms |
Key Findings
- Performance: ECDSA is ~12x faster than RSA (91% improvement)
- URL Length: 55.1% shorter URLs (RSA: 448 chars → ECDSA: 201 chars)
- Consistency: Lower standard deviation shows more stable performance
Real URL Examples
RSA Signed URL (448 characters):
https://example.com/private-files/uploadtest.jpg?Expires=1757511063&Signature=TNGmM2jrc5GRTalKgYhdZla1uaR~gOiX4HevKDMBbe5JkecwxGe0VoCqXB5KnCPgetRbbBE6JCtOdCYiTwGYxKpByOBJTMaS5Z3H9rqhln~wqQ0KZ-q5-lqvEPsxXlbBXbzJ0MDwNgzcCcu3GavsYGiceFr0veGw5RuYNLSs49HdFUKtdk~7wpI~bjdHzLDSaxoTKtIz0HDgii~VTPP769X~aOmG7~W0hm23nBP4WcTDe6Z8YvDRr61TqjixkNYrh4FiuUFFVuA2Tn0FUuaxcU5qVhtcl0ng8QqoyHUwWFju65h6g0TUM2iueJudQtV-CcoYf-UHlVOGQ39pnG9HxQ__&Key-Pair-Id=ZZZZZZZZZZZZZ
ECDSA Signed URL (201 characters):
https://example.com/private-files/uploadtest.jpg?Expires=1757511063&Signature=MEQCIBO~LD6qEaVjiwGFFF233dOB~XJvi7SPhubaN0FjFsigAiBlLZAYz9sCp6aY93bE9z0SuZDhEH3Pw8uL-9rPODVbQw__&Key-Pair-Id=WWWWWWWWWWWWWW
When to Use ECDSA
ECDSA is particularly beneficial for:
- High-volume URL generation: APIs generating many signed URLs
- Mobile/IoT devices: Resource-constrained environments
- URL length constraints: SMS, QR codes, social media
- Real-time applications: Where response time is critical
Conclusion
CloudFront's ECDSA support delivers significant performance improvements and URL size reductions. For high-load systems or resource-constrained environments, ECDSA provides substantial benefits while maintaining the same security level as RSA.
The 91% performance improvement and 53% URL size reduction make ECDSA a compelling choice for modern applications requiring efficient signed URL generation.
Resources
Have you tried ECDSA signed URLs in your CloudFront setup? Share your experience in the comments!
Top comments (0)