Students:
- Lê Trí Đức - 24520009
- Phạm Nguyễn Thành Long - 24521011
Lecturer: Nguyễn Ngọc Tự
- Scenario: Secure service company uses RSA-based algorithms for securing transactions and digital signatures. They want to ensure the robustness of their RSA implementation against potential attacks.
- Gaps: While RSA is a widely accepted and used in public-key cryptosystem, improper implementations or usage of weak parameters can lead to vulnerabilities.
- Motivations: To ensure the integrity and confidentiality of financial transactions and to maintain the trust of clients and stakeholders.
In this project we focus on RSA-based encryption and RSA-based digital signatures, with an emphasis on two signature variants: PKCS#1 v1.5 and RSASSA-PSS.
An RSA key pair is generated as follows:
- Choose two large primes
$p, q$ and compute the modulus$N = p q$ . - Compute
$\varphi(N) = (p-1)(q-1)$ . - Choose a public exponent
$e$ such that$\gcd(e, \varphi(N)) = 1$ . - Compute the private exponent
$d$ such that $$ e \cdot d \equiv 1 \pmod{\varphi(N)}. $$
In short:
-
Public key:
$(N, e)$ -
Private key:
$(N, d)$
The “textbook” RSA operations are:
-
Encryption:
$c = m^e \bmod N$ -
Decryption:
$m = c^d \bmod N$
Here
Textbook RSA is not secure in practice because:
- It is deterministic (encrypting the same message always gives the same ciphertext).
- It does not provide semantic security, and is vulnerable to chosen-plaintext and chosen-ciphertext attacks.
Real-world systems therefore never use textbook RSA; they always wrap it with a padding/encoding scheme.
Computing
-
$d_p = d \bmod (p-1)$ -
$d_q = d \bmod (q-1)$ -
$u = q^{-1} \bmod p$ (the modular inverse of$q$ modulo$p$ ) -
Encryption CRT: Same as textbook RSA
-
Decryption CRT:
-
$\displaystyle m_{p} \equiv c^{d_{p}} \ (\bmod p) ,\ m_{q} \ \equiv c^{d_{q}} \ (\bmod q)$ -
$\displaystyle h\equiv ( m_{p} -m_{q}) u\ (\bmod p)$ -
$\displaystyle m\equiv m_{q} +q\cdotp h( \ \bmod n)$ -
Output
$\displaystyle m$
RSA signatures use the same key pair
- Signing (with the private key):
$s = m^d \bmod N$ - Verification (with the public key): check
$m \stackrel{?}{=} s^e \bmod N$
In practice,
Different signature schemes define different ways to encode the hash of a message before applying RSA.
We focus on two main signature schemes:
PKCS#1 v1.5 has long been the most widely deployed RSA signature scheme in practice. The original definition of the RSASSA-PKCS1-v1_5 algorithm is given in RFC 3447, available at https://datatracker.ietf.org/doc/html/rfc3447.
High-level idea:
- Given a message
$M$ , compute its hash$H = \text{Hash}(M)$ (e.g., SHA-256). - Build an encoded message (EM) of the form:
0x00 || 0x01 || 0xFF ... FF || 0x00 || T- where
Tis an ASN.1/DER encoding of the hash algorithm identifier and the hash value$H$ .
- Interpret EM as an integer
$m_{\text{EM}}$ and compute the signature:-
$s = m_{\text{EM}}^d \bmod N$ .
-
- Verification recomputes EM from the message and checks:
-
$s^e \bmod N$ equals the expected EM.
-
Properties:
- Deterministic: signing the same message twice yields the same signature.
- Very widely supported (TLS, X.509 certificates, code signing, JWT RS256 in some libraries, etc.).
- Known to be fragile if verification is not implemented strictly:
- Lenient parsing, acceptance of malformed paddings, or incorrect handling of the ASN.1 structure can lead to signature forgery attacks.
- Because of its structured deterministic padding, it is harder to prove security in a tight theoretical sense.
RSASSA-PSS (Probabilistic Signature Scheme) is a newer RSA signature scheme designed with provable security in mind.
High-level idea:
- Given a message
$M$ , compute$H = \text{Hash}(M)$ . - Generate a random salt and build an encoded message (EM) using a randomized padding construction:
- EM combines
$H$ , the salt, and some fixed bits via a mask generation function (MGF).
- EM combines
- Interpret EM as an integer
$m_{\text{EM}}$ and compute:-
$s = m_{\text{EM}}^d \bmod N$ .
-
- Verification recomputes EM (including deriving/checking the salt structure) and checks:
-
$s^e \bmod N$ equals the expected EM.
-
Properties:
- Probabilistic: signing the same message multiple times produces different signatures thanks to the random salt.
- Comes with strong theoretical guarantees: under standard assumptions (e.g., hardness of RSA and properties of the hash/MGF), RSASSA-PSS can be proven secure against adaptive chosen-message attacks.
- Recommended by modern standards for new applications:
- Often preferred over PKCS#1 v1.5 in new protocols and certificate profiles.
In this project, PSS plays the role of a “modern, more robust” signature scheme that we can compare against PKCS#1 v1.5 in terms of:
- Security guarantees,
- Resistance to subtle parsing bugs,
- Deployment challenges (library support, compatibility with existing systems).
- RSA defines a core mathematical primitive using
$(N, e, d)$ ; encryption and signatures are different modes built on top. - Real-world security critically depends on padding and encoding schemes, not just on the hardness of factoring
$N$ . -
PKCS#1 v1.5 signatures:
- Deterministic, widely deployed.
- Sensitive to implementation bugs and lenient parsing.
-
RSASSA-PSS:
- Randomized, with stronger theoretical security.
- Recommended as the preferred scheme for new designs and migrations.
These schemes and their differences are central to our later sections on attack experiments (Bleichenbacher, timing, fault attacks) and on deployment weakness analysis.
In our setting, a trusted key-generation algorithm
The RSA public key contains
In practice, this modulus
- Server certificates used in TLS connections (e.g., for online payments or secure APIs),
- Digital-signature keys used to sign transactions, contracts, or software updates,
- Possibly hardware tokens / HSMs used by the service provider.
An external adversary
The most direct way for
The factoring assumption states that, for moduli generated by
If the factoring assumption fails for our generated moduli, the consequences for the system are severe:
-
Private-key recovery:
Once$\mathcal{A}$ computes$p$ and$q$ , it can derive$\varphi(N)$ and recover the private exponent$d$ .
At this point the adversary has a full copy of the RSA private key. -
Loss of confidentiality:
The attacker can decrypt any ciphertext encrypted under the public key$(N, e)$ .
This includes past recorded traffic (if stored), leading to retrospective disclosure of sensitive data such as credentials, financial information, or session keys. -
Loss of integrity, authenticity, and non-repudiation:
With the private key, the adversary can forge valid RSA signatures that are indistinguishable from signatures produced by the legitimate key owner.
This enables impersonation of servers, forging of transaction approvals, or signing of malicious software updates. -
System-wide impact if keys are re-used:
In many real deployments, the same RSA key pair is used across multiple services (e.g., web server, VPN, code signing).
Factoring a single modulus$N$ may compromise multiple independent security functions at once.
In short, breaking the factoring assumption directly breaks the security of any RSA-based encryption or signature scheme built on that modulus.
To rely on RSA securely, the system’s design must ensure that the factoring assumption is realistic for all deployed moduli:
-
Goal 1 – Hard-to-factor moduli (sufficient key sizes):
Choose modulus sizes$N$ large enough that the best known classical factoring algorithms (e.g., Number Field Sieve) remain computationally infeasible in practice.
For current deployments, this typically means at least 2048-bit moduli, and moving to 3072-bit or higher for long-term security. -
Goal 2 – High-quality modulus generation:
Ensure$\text{GenModulus}$ uses cryptographically secure randomness to generate$p$ and$q$ :- primes of appropriate size,
- not too close to each other,
- not taken from small or structured sets.
This avoids “weak RSA keys” that might be factored using specialized attacks (e.g., shared-prime or low-entropy key attacks).
-
Goal 3 – Key isolation and minimal reuse:
Avoid using the same modulus$N$ for many independent security domains (e.g., mixing TLS, code signing, and document signing with one key).
Even if one modulus were factored, the blast radius should be limited. -
Goal 4 – Forward-looking protection against advances in factoring:
Monitor cryptanalytic progress and adjust key sizes and lifetimes accordingly.
Plan for migration away from factoring-based schemes (e.g., toward post-quantum cryptography) in anticipation of quantum attacks (such as Shor’s algorithm) that would make factoring easy.
These goals collectively formalize what it means, at the system level, to “assume factoring is hard”: we must choose parameters, algorithms, and operational practices so that any realistic adversary’s success probability in factoring
- Python 3.x
Install: https://www.python.org/downloads/
- Sagemath
See the installation guide here: https://doc.sagemath.org/html/en/installation/index.html. For the sake of convenience, it should be installed using conda-forge.
After installing, activate it with the following command:
duccorp@DESKTOP-RH0V9GH:~/RSA-Based-Cryptography$ source ~/miniforge3/bin/activate
(base) duccorp@DESKTOP-RH0V9GH:~/RSA-Based-Cryptography$ conda activate sage
(sage) duccorp@DESKTOP-RH0V9GH:~/RSA-Based-Cryptography$ sage
┌────────────────────────────────────────────────────────────────────┐
│ SageMath version 10.6, Release Date: 2025-03-31 │
│ Using Python 3.11.13. Type "help()" for help. │
└────────────────────────────────────────────────────────────────────┘
sage:
You can check your SageMath version by
(sage) duccorp@DESKTOP-RH0V9GH:~/RSA-Based-Cryptography$ sage --version
SageMath version 10.6, Release Date: 2025-03-31
In Visual Studio Code, press Ctrl+Shift+P and choose the correct Python interpreter before coding.
Import it with
from sage.all import * - Pycryptodome
Docs and installation guide of the library: https://pycryptodome.readthedocs.io/en/latest/src/introduction.html. PyCryptodome provides many cryptographic functions for working with RSA
We will focus on some specific cases where the RSA parameters do not satisfy the security conditions assumed by the GenModulus algorithm in the factoring assumption. These “non-ideal” choices produce vulnerable instances that are easier to analyze and attack.
In the factoring attack model, the attacker only sees the public RSA key
If the attacker recovers the two primes
- compute
$\varphi(N) = (p-1)(q-1)$ , - compute the private exponent $$ d = e^{-1} \bmod \varphi(N), $$
- obtain the full private key
$(N, d)$ .
At this point, RSA is completely broken: the attacker can decrypt any ciphertext
This directly violates the factoring assumption in the GenModulus experiment.
In practice, factoring is done using a dedicated integer-factoring algorithm. For large “random-looking” RSA moduli, the fastest known classical algorithm is the General Number Field Sieve (GNFS). In this project we treat GNFS as a black-box factoring oracle:
- Input: the modulus
$N$ , - Output: (possibly) two primes
$p, q$ with$N = p q$ .
Factoring attacks become feasible when the RSA parameters do not satisfy the security conditions of GenModulus, for example:
-
$N$ is too small (toy bitlengths used in lab), - the key generation is weak (poor randomness, repeated primes, special structure in
$p$ or$q$ ).
Given the public key
- Run a factoring algorithm (conceptually, GNFS) on
$N$ to obtain$p$ and$q$ such that$N = p q$ . - Compute
$\varphi(N) = (p-1)(q-1)$ . - Compute the private exponent
$d = e^{-1} \bmod \varphi(N)$ . - Use
$(N, d)$ to:- decrypt sample ciphertexts
$c$ as$m = c^d \bmod N$ , - or forge signatures
$s = m^d \bmod N$ .
- decrypt sample ciphertexts
Wiener's attack is an attack on RSA that uses continued fractions to find the private exponent when it is small. Specifically when it is less than
Wiener's attack is based on the following theorem:
Let
Suppose we have the public key
- Convert the fraction
$\dfrac{e}{n}$ into a continued fraction
- Iterate over each convergent of this continued fraction:
-
For each convergent, say
$\dfrac{k}{d}$ , check if it can be the correct one by doing:- Set the numerator to be
$k$ and the denominator to be$d$ . - Check if
$d$ is odd; if not, move on to the next convergent. - Check if
$ed \equiv 1 \pmod{k}$ ; if not, move on to the next convergent. - Set
$\varphi(n) = \frac{ed - 1}{k}$ and find the roots of the polynomial$x^2 - (n - \varphi(n) + 1)x + n.$ - If the roots are integers, then we have found
$d$ (otherwise, move on to the next convergent).
- Set the numerator to be
-
If all convergents have been tried and none of them work, then the given RSA parameters are not vulnerable to Wiener's attack.
The most powerful attacks on low public exponent RSA are based on a theorem due to Coppersmith. Coppersmith's theorem has many applications, only some of which will be covered here.
Theorem (Coppersmith):
Let
Set
The theorem provides an algorithm for efficiently finding all roots of
In practice, RSA implementations almost always use CRT optimization to speed up private-key operations (decryption and signing).
Instead of computing
they use the precomputed CRT parameters:
-
$N = p q$ , -
$d_p = d \bmod (p - 1)$ , -
$d_q = d \bmod (q - 1)$ , -
$u = p^{-1} \bmod q$ (or equivalently$q^{-1} \bmod p$ , depending on convention).
The RSA-CRT signing algorithm is:
- Compute partial signatures
- Recombine using CRT, e.g.
The signature
A fault attack on RSA-CRT assumes the attacker can induce a computational error during this CRT process (e.g. by voltage/clock glitching, laser fault injection, or any physical disturbance) and obtain at least one faulty signature
Suppose a fault occurs only in one of the two branches, say in the computation modulo
- Instead of
$s_p = m^{d_p} \bmod p$ , the device computes some corrupted value$s_p'$ . - The branch modulo
$q$ is still correct:$s_q' = s_q$ .
After CRT recombination, the faulty signature
-
$s' \equiv s_p' \pmod{p}$ (wrong), -
$s' \equiv s_q \pmod{q}$ (still correct).
The correct signature
-
$s \equiv s_p \pmod{p}$ , -
$s \equiv s_q \pmod{q}$ .
Therefore, modulo
so
but in general
Hence,
So the attacker can recover
Once
- Twenty Years of Attacks on the RSA Cryptosystem, Dan Boneh
- Introduction to Modern Cryptography, Second Edition
- Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption Standard PKCS #1
- Modulus Fault Attacks Against RSA-CRT Signatures
- New Partial Key Exposure Attacks on RSA
- Small Public Exponent Brings More: Improved Partial Key Exposure Attacks against RSA
- Cache-Timing Attacks on RSA Key Generation
- Timing Attacks on Software Implementation of RSA
- On the Security of the PKCS#1 v1.5 Signature Scheme