RSA 基础
欧拉函数 φ(n)
φ(n) 表示 “小于等于 n 且与 n 互质的正整数的个数”
如果 n 是质数 p,那么 φ(p) = p - 1(因为 1,2,…,p-1 都和 p 互质)
如果 n = p * q,且 p、q 都是质数,那么
φ(n) = (p - 1) * (q - 1)例如 p = 5, q = 11,则 n = 55,φ(55) = 4 * 10 = 40
密钥生成
选两个大质数 p 和 q
实际中 p、q 有 1024 位或 2048 位,这里我们用小数字演示
1 | p = 61 |
计算 n 和 φ(n)
1 | n = p * q = 61 * 53 = 3233 |
选公钥指数 e
要求:
1 < e < φ(n)
e 与 φ(n) 互质(即最大公约数为 1)
小例子中我们选 e = 17
计算私钥指数 d
d 是 e 在模 φ(n) 下的乘法逆元,即满足:
1 | (e * d) mod φ(n) = 1 |
换句话说,存在整数 k 使得:
1 | e * d = k * φ(n) + 1 |
计算 d 可以用扩展欧几里得算法。小例子中,可以验证 d = 2753
加密过程
加密公式:
1 | c = (m ^ e) mod n |
例子:加密明文 m = 65
1 | c = 65 ^ 17 mod 3233 |
直接算 65^17 巨大,但模运算可以逐步取余。结果:
1 | c = 2790 |
解密过程
1 | m = (c ^ d) mod n |
例子:c = 2790, d = 2753, n = 3233
1 | m = 2790 ^ 2753 mod 3233 = 65 |
推导过程
即要证明:
1 | c^d ≡ m (mod n) |
将 c = m^e mod n 代入 c^d:
1 | c^d ≡ (m^e)^d = m^(e*d) (mod n) |
利用 ed = kφ(n) + 1:
1 | m^(e*d) = m^(k*φ(n) + 1) = [m^(φ(n))]^k * m |
所以:
1 | c^d ≡ [m^(φ(n))]^k * m (mod n) |
欧拉定理说:如果 m 和 n 互质(即 gcd(m, n) = 1),那么
1 | m^(φ(n)) ≡ 1 (mod n) |
因此
1 | [m^(φ(n))]^k ≡ 1^k = 1 (mod n) |
于是
1 | c^d ≡ 1 * m = m (mod n) |
实战案例
equationSet(提公因数 p)

解题技巧先放前面:
- 符号化:所有给出的数值用数学符号表示出来,并建立它们之间的关系
- 寻找公因数:如果给出的两个大数 A 和 B 都是由相同的素数因子构成的,那么
GCD(A, B)往往是解密的关键 - 确定解题路径:一旦
p被分解出来,接下来就要想方设法得到q和r的信息
题目给出代码
1 | from Crypto.Util.number import * |
转换成数学公式
1 | n = p * q * r |
我们可以清楚地看到,p 是 n 和 t 的公共因子
那 GCD(n, t) 会正好是 p 吗?会不会包含其他因子?
由于 q 和 r 都是生成的 512 位随机大素数,它们互质,且它们的和 q+r 极大概率与它们的积 qr 互质
因此 GCD(qr, q+r) = 1
结论:直接计算 GCD(n, t) 就能提取出素数 p
观察公因数 是 Crypto 选手的直觉。看到 n 和 t 有明显的公共结构(都含有 p),第一时间想到的就是 GCD
1 | from Crypto.Util.number import * |
easyRSA(线性组合泄露 d 与 φ(n))

1 | from Crypto.Util.number import * |
RSA 里,我们有:
p,q两个大素数n = p * qφ(n) = (p-1)*(q-1)公钥指数
e = 65537(题目固定)私钥指数
d满足e * d ≡ 1 (mod φ(n))
这等价于存在一个整数 k,使得:
1 | e * d = k * φ(n) + 1 |
即
1 | d = (k * φ(n) + 1) / e |
题目除了给 n 和密文 c,还给了
1 | x = 11 * d + 7 * φ(n) |
也就是说,x 是 d 和 φ(n) 的一个线性组合,系数分别是 11 和 7
将上面 d 的表达式代入 x
1 | x = 11 * [ (kφ + 1)/e ] + 7φ |
两边同时乘以 e,去掉分母
1 | e * x = 11 * (kφ + 1) + 7eφ |
展开
1 | e * x = 11kφ + 11 + 7eφ |
把常数项移到左边,含 φ 的项合并
1 | e * x - 11 = (11k + 7e) φ |
记 T = ex - 11,则
1 | T = (11k + 7e) * φ |
这是一个关键等式,T 是 φ 的整数倍,倍数 A = 11k + 7e 依赖于未知的 k
从 e * d = k φ + 1 得
1 | k = (e * d - 1) / φ |
因为 d < φ(实际上 d 是模 φ 下的逆元,通常比 φ 略小),所以
1 | e * d - 1 < e * φ - 1 → k < e |
所以思路:
计算
T = e * x - 11(已知x和e)对每个可能的
k从 0 到e-1,计算A = 11k + 7e如果
A能整除T,那么φ = T // A就是一个候选的欧拉函数值用这个
φ去分解n,因为p + q = n - φ + 1,p * q = n,所以p和q是二次方程X^2 - (p + q)X + n = 0的两个根判断
p和q是否为整数且满足p * q == n,若是,则分解成功
已知
1 | s = p + q |
根据韦达定理,以 p 和 q 构造一个二次方程
1 | (t-q)(t-p) = 0 |
把已知条件带入得到
1 | t² - s * t + n = 0 |
对于任意二次方程,判别式公式为
1 | at² + bt + c = 0 |
代入得到
1 | a = 1,b = -s,c = n |
如果判别式是完全平方数,方程就有整数解
1 | p = (s + √Δ)/2 |
1 | from Crypto.Util.number import * |
little RSA(分解 n)
题目给了
1 | c=32949 |
分解 n 得到 p,q

1 | from Crypto.Util.number import long_to_bytes |
解出为 18429 解压密码
Rivest Shamir Adleman(分解 n)
和上题一样的方法

1 | from math import isqrt |