👋 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)