RSA-2048 Security-Focused API Documentation
Version: 1.0
Last Updated: 2025-09-08
Security Classification: PUBLIC
Author: Phantom (phantom@metamui.id)
⚠️ CRITICAL WARNING
RSA-2048 is a TRANSITIONAL algorithm vulnerable to quantum attacks. It will be DEPRECATED by 2030.
- Quantum Security: 0 bits (completely broken by Shor’s algorithm)
- Classical Security: ~112 bits
- Migration Required: All systems must migrate to ML-KEM or other PQC algorithms
Overview
RSA-2048 is provided ONLY for backward compatibility and hybrid cryptography during the migration to post-quantum algorithms. This documentation provides security-focused guidance for the transitional use of RSA-2048.
Security Level: 112 bits (classical only)
Key Size: 2048 bits (256 bytes)
Signature Size: 256 bytes
Ciphertext Size: 256 bytes
Security Warnings ⚠️
- Quantum Vulnerability: RSA-2048 offers ZERO protection against quantum computers
- Deprecation Timeline: Will be removed from the library by 2030
- Padding Oracles: MUST use OAEP for encryption and PSS for signatures
- Timing Attacks: Implementation uses CRT with blinding for mitigation
- Key Generation: ~500ms generation time may leak timing information
- Factorization Risk: Advances in classical factorization reduce security margin
API Functions
generate_key() -> PrivateKey
Security Contract:
- Preconditions:
- System CSPRNG must provide at least 256 bits of entropy
- Prime generation must use Miller-Rabin with ≥20 rounds
- p and q must differ by at least 2^100
- Postconditions:
- n = p × q has exactly 2048 bits
- gcd(e, φ(n)) = 1 where e = 65537
- Private exponent d satisfies e × d ≡ 1 (mod φ(n))
- CRT parameters (dp, dq, qinv) are precomputed
Attack Resistance: | Attack Type | Protected | Notes | |————-|———–|——-| | Weak RNG | ✅ | Uses system CSPRNG | | Small Prime Factors | ✅ | Enforces minimum prime size | | Timing Attack | ⚠️ | Generation time varies | | Quantum Attack | ❌ | Completely vulnerable to Shor’s algorithm | | Factorization | ⚠️ | 112-bit classical security |
encrypt(message: bytes, public_key: PublicKey) -> bytes
Security Contract:
- Preconditions:
- Message length ≤ 190 bytes (for OAEP with SHA-256)
- OAEP padding MUST be applied with SHA-256
- Random seed must have 32 bytes from CSPRNG
- Postconditions:
- Ciphertext is exactly 256 bytes
- Different encryptions of same message produce different ciphertexts
- OAEP padding prevents chosen-ciphertext attacks
Attack Resistance: | Attack Type | Protected | Notes | |————-|———–|——-| | Padding Oracle | ✅ | OAEP prevents oracle attacks | | Chosen Ciphertext | ✅ | OAEP-SHA256 is IND-CCA2 | | Timing Attack | ✅ | Public operation is naturally constant-time | | Quantum Attack | ❌ | Broken by quantum computers | | Bleichenbacher | ✅ | OAEP prevents this attack |
decrypt(ciphertext: bytes, private_key: PrivateKey) -> bytes
Security Contract:
- Preconditions:
- Ciphertext must be exactly 256 bytes
- Private key must be protected in memory
- CRT blinding must be applied
- Postconditions:
- Returns plaintext or error (no partial information)
- All temporary values are cleared from memory
- Timing is independent of ciphertext value (via blinding)
Attack Resistance: | Attack Type | Protected | Notes | |————-|———–|——-| | Timing Attack | ✅ | CRT with blinding | | Padding Oracle | ✅ | OAEP validation in constant time | | Fault Injection | ⚠️ | CRT may be vulnerable | | Memory Disclosure | ✅ | Secure memory clearing | | Quantum Attack | ❌ | Private key recovery via Shor’s |
sign(message: bytes, private_key: PrivateKey) -> bytes
Security Contract:
- Preconditions:
- Message is hashed with SHA-256 before signing
- PSS padding with SHA-256 and salt length = hash length
- Random salt must be 32 bytes from CSPRNG
- Postconditions:
- Signature is exactly 256 bytes
- Different signatures for same message (probabilistic)
- PSS padding prevents forgery attacks
Attack Resistance: | Attack Type | Protected | Notes | |————-|———–|——-| | Forgery | ✅ | PSS prevents existential forgery | | Timing Attack | ✅ | CRT with blinding | | Fault Attack | ⚠️ | Bellcore attack possible on CRT | | Quantum Attack | ❌ | Signatures forgeable with quantum computer |
verify(message: bytes, signature: bytes, public_key: PublicKey) -> bool
Security Contract:
- Preconditions:
- Signature must be exactly 256 bytes
- Message is hashed with SHA-256
- PSS verification with same parameters as signing
- Postconditions:
- Returns true only for valid signatures
- No information leakage on invalid signatures
- Verification time is constant
Attack Resistance: | Attack Type | Protected | Notes | |————-|———–|——-| | Signature Malleability | ✅ | PSS prevents malleability | | Timing Attack | ✅ | Public operation | | Quantum Attack | ❌ | Verification broken by quantum computer |
Implementation Security
Memory Security
# Critical: Clear private key material after use
def cleanup_private_key(key):
key.d = secure_clear(key.d)
key.p = secure_clear(key.p)
key.q = secure_clear(key.q)
key.dp = secure_clear(key.dp)
key.dq = secure_clear(key.dq)
key.qinv = secure_clear(key.qinv)
CRT Blinding
# Prevent timing attacks during private key operations
def decrypt_with_blinding(ciphertext, private_key):
r = random_coprime(private_key.n)
r_inv = mod_inverse(r, private_key.n)
# Blind the ciphertext
blinded = (ciphertext * pow(r, e, n)) % n
# Perform CRT decryption
result = crt_decrypt(blinded, private_key)
# Unblind the result
plaintext = (result * r_inv) % n
# Clear temporary values
secure_clear(r, r_inv, blinded, result)
return plaintext
Migration Strategy
Hybrid Mode Implementation
def hybrid_encrypt(message, rsa_key, mlkem_key):
"""Encrypt with both RSA and ML-KEM for transition period"""
# Generate shared secret with ML-KEM
mlkem_ct, shared_secret = mlkem_key.encapsulate()
# Derive encryption key
enc_key = kdf(shared_secret)
# Encrypt message with AES-256-GCM
aes_ct = aes_gcm_encrypt(message, enc_key)
# Also encrypt key with RSA for compatibility
rsa_ct = rsa_key.encrypt(enc_key)
return {
'mlkem_ct': mlkem_ct, # Quantum-safe
'rsa_ct': rsa_ct, # Legacy compatibility
'aes_ct': aes_ct # Actual message
}
Deprecation Warnings
import warnings
from datetime import datetime
def rsa_operation_wrapper(func):
def wrapper(*args, **kwargs):
if datetime.now().year >= 2028:
warnings.warn(
"RSA-2048 will be deprecated in 2030. "
"Migrate to ML-KEM immediately.",
DeprecationWarning,
stacklevel=2
)
return func(*args, **kwargs)
return wrapper
Security Audit Checklist
Required Validations
- OAEP padding with SHA-256 for all encryption
- PSS padding with SHA-256 for all signatures
- CRT blinding for all private key operations
- Secure memory clearing for all sensitive data
- Minimum prime difference of 2^100
- Miller-Rabin with ≥20 rounds for prime generation
- No RSA encryption without padding
- No deterministic signatures (PSS salt required)
Migration Requirements
- Hybrid mode implemented with PQC algorithm
- Deprecation warnings configured
- Migration plan documented
- PQC algorithm selected and tested
- Timeline for RSA removal established
Threat Summary
| Threat | Impact | Mitigation |
|---|---|---|
| Quantum Attack | CRITICAL | Migrate to PQC immediately |
| Factorization | HIGH | Monitor advances, enforce 2030 deadline |
| Padding Oracle | HIGH | Strict OAEP/PSS implementation |
| Timing Attack | MEDIUM | CRT blinding implemented |
| Fault Injection | MEDIUM | Limited mitigation available |
| Bleichenbacher | HIGH | OAEP prevents this |
| Small Factors | HIGH | Strong prime generation |
Compliance Notes
- NIST: RSA-2048 is approved until 2030 for legacy use only
- BSI: Recommends immediate migration to PQC
- ANSSI: RSA-2048 deprecated for new systems
- NSA: Commercial National Security Algorithm (CNSA) requires PQC
References
- PKCS #1 v2.2: RSA Cryptography Specifications
- NIST SP 800-56B Rev. 2: Recommendation for Pair-Wise Key-Establishment Using RSA
- NIST SP 800-131A Rev. 2: Transitioning the Use of Cryptographic Algorithms
- RSA to PQC Migration Guide