对RSA私钥泄露攻击
RSA基本关系
核心方程
- \(n = p \cdot q\),其中\(p\)、\(q\)为大素数
- \(\phi(n) = (p-1)(q-1)\)
- \(e \cdot d \equiv 1 \pmod{\phi(n)} \Rightarrow e \cdot d = k \cdot \phi(n) + 1\)
关键推导
由欧拉定理:对于任意\(a\)满足\(\gcd(a, n) = 1\),有:
\[a^{\phi(n)} \equiv 1 \pmod{n}
\]
代入\(e \cdot d = k \cdot \phi(n) + 1\)得:
\[a^{e \cdot d - 1} = a^{k \cdot \phi(n)} = (a^{\phi(n)})^k \equiv 1^k \equiv 1 \pmod{n}
\]
因此对任意与\(n\)互素的\(a\):
\[a^{e \cdot d - 1} \equiv 1 \pmod{n} \quad
\]
攻击原理推导
步骤1:指数分解
设:
\[e \cdot d - 1 = 2^s \cdot t
\]
其中\(t\)为奇数(不断除以2直到得到奇数)
步骤2:构建平方序列
由核心等式:\(a^{2^s \cdot t} \equiv 1 \pmod{n}\)
定义序列:
\[\begin{aligned}
x_0 &= a^t \pmod{n} \\
x_1 &= x_0^2 = a^{2t} \pmod{n} \\
x_2 &= x_1^2 = a^{2^2 t} \pmod{n} \\
&\vdots \\
x_s &= x_{s-1}^2 = a^{2^s t} \equiv 1 \pmod{n}
\end{aligned}
\]
步骤3:寻找非平凡平方根
引理1:如果存在\(i\)(\(1 \leq i \leq s\))使得:
\[x_i \equiv 1 \pmod{n} \quad \text{且} \quad x_{i-1} \not\equiv \pm 1 \pmod{n}
\]
则\(x_{i-1}\)是\(1\)模\(n\)的一个非平凡平方根。
证明:
- \(x_i = x_{i-1}^2 \equiv 1 \pmod{n}\) ⇒ \(x_{i-1}^2 \equiv 1 \pmod{n}\)
- \(x_{i-1} \not\equiv \pm 1 \pmod{n}\) ⇒ 平方根是非平凡的
非平凡平方根分解\(n\)
定理1
如果\(x\)满足:
- \(x^2 \equiv 1 \pmod{n}\)
- \(x \not\equiv \pm 1 \pmod{n}\)
则\(\gcd(x-1, n)\)和\(\gcd(x+1, n)\)都是\(n\)的非平凡因子。
证明:
- \(x^2 \equiv 1 \pmod{n}\) ⇒ \(x^2 - 1 \equiv 0 \pmod{n}\) ⇒ \(n \mid (x-1)(x+1)\)
- \(x \not\equiv 1 \pmod{n}\) ⇒ \(n \nmid (x-1)\)
- \(x \not\equiv -1 \pmod{n}\) ⇒ \(n \nmid (x+1)\)
- \(n = p \cdot q\)整除\((x-1)(x+1)\),但\(p\)、\(q\)不能同时整除\((x-1)\)或\((x+1)\)(否则会整除它们的差\(2\))
- 因此:
- 情况A:\(p \mid (x-1)\)且\(q \mid (x+1)\)
- 情况B:\(p \mid (x+1)\)且\(q \mid (x-1)\)
- 无论哪种情况,\(\gcd(x-1, n)\)和\(\gcd(x+1, n)\)中至少有一个是\(n\)的非平凡因子
成功分析
在\(\mathbb{Z}_n\)中,方程\(x^2 \equiv 1 \pmod{n}\)有4个解:
- \(x \equiv 1 \pmod{p}\)且\(x \equiv 1 \pmod{q}\) ⇒ \(x \equiv 1 \pmod{n}\)
- \(x \equiv 1 \pmod{p}\)且\(x \equiv -1 \pmod{q}\) ⇒ \(x \equiv c_1 \pmod{n}\)
- \(x \equiv -1 \pmod{p}\)且\(x \equiv 1 \pmod{q}\) ⇒ \(x \equiv c_2 \pmod{n}\)
- \(x \equiv -1 \pmod{p}\)且\(x \equiv -1 \pmod{q}\) ⇒ \(x \equiv -1 \pmod{n}\)
其中\(c_1\)、\(c_2\)是非平凡解。
成功率分析
设:
- \(p-1 = 2^{\alpha} u\),\(u\)为奇数
- \(q-1 = 2^{\beta} v\),\(v\)为奇数
- 对于随机\(a\),在\(\mathbb{Z}_p^*\)中\(a\)的阶为\(2^{\gamma_p} w_p\)
- 在\(\mathbb{Z}_q^*\)中\(a\)的阶为\(2^{\gamma_q} w_q\)
则:
\[i_p = \max(0, \alpha - \gamma_p), \quad i_q = \max(0, \beta - \gamma_q)
\]
当\(i_p \neq i_q\)时,算法成功概率至少为\(1/2\)。
完整算法描述
输入
- RSA公钥\((n, e)\)
- 私钥\(d\)
输出
- \(n\)的素因子\(p\)和\(q\)
算法步骤
def factorize_with_d(n, e, d):
# 1. 计算并分解指数
M = e * d - 1
s = 0
t = M
while t % 2 == 0:
t //= 2
s += 1
# 2. 随机尝试
for attempt in range(max_attempts):
a = random.randint(2, n-1)
# 如果a与n不互素,直接找到因子
g = gcd(a, n)
if g > 1:
return g, n // g
# 3. 计算平方序列
x = pow(a, t, n)
# 4. 寻找非平凡平方根
for i in range(s):
x_prev = x
x = (x * x) % n
if x == 1 and x_prev != 1 and x_prev != n-1:
# 找到非平凡平方根
p = gcd(x_prev - 1, n)
q = gcd(x_prev + 1, n)
return (p, n//p) if p > 1 else (q, n//q)
if x == n-1:
break # 平凡情况,重新选择a
return None # 失败
示例
\(n = 15 = 3 \cdot 5\),\(\phi(n) = 8\)
已知\(e=3\),则\(d=3\)(因为\(3 \times 3 = 9 \equiv 1 \pmod{8}\))
-
计算指数:
\[M = e \cdot d - 1 = 9 - 1 = 8 = 2^3 \cdot 1 \]所以\(s=3\),\(t=1\)
-
选择\(a=2\):
- \(x_0 = 2^1 \bmod 15 = 2\)
- \(x_1 = 2^2 \bmod 15 = 4\)
- \(x_2 = 4^2 \bmod 15 = 1\)
-
发现非平凡平方根:
- \(i=2\)时\(x_2 = 1\)
- \(x_1 = 4 \neq \pm 1 \pmod{15}\)
- 因此\(x_1 = 4\)是非平凡平方根
-
计算因子:
- \(\gcd(4-1, 15) = \gcd(3, 15) = 3\) ⇒ \(p=3\)
- \(q = 15/3 = 5\)
-
验证:\(3 \times 5 = 15\) ✓
实现
rsa_d_leakage_attack
"""
RSA分解算法 - 已知解密指数d和公钥(n, e)分解n
当已知RSA的解密指数d和公钥(n, e)时,可以通过以下方法分解n:
1. 利用 ed ≡ 1 (mod φ(n)) 的关系
2. 得出 ed - 1 = kφ(n)
3. 随机构造一个数a,计算a^k mod n
4. 通过寻找非平凡的平方根来分解n
"""
import random
def extended_gcd(a, b):
if a == 0:
return b, 0, 1
gcd, x1, y1 = extended_gcd(b % a, a)
x = y1 - (b // a) * x1
y = x1
return gcd, x, y
def mod_inverse(a, m):
gcd, x, _ = extended_gcd(a % m, m)
if gcd != 1:
raise ValueError()
return (x % m + m) % m
def power_mod(base, exp, mod):
result = 1
base = base % mod
while exp > 0:
if exp % 2 == 1:
result = (result * base) % mod
exp = exp >> 1
base = (base * base) % mod
return result
def gcd(a, b):
while b:
a, b = b, a % b
return a
def factorize_with_d(n, e, d):
"""
利用已知的解密指数d分解RSA模数n
"""
print(f"开始分解: n = {n}, e = {e}, d = {d}")
ed_minus_1 = e * d - 1
print(f"步骤1: 计算 ed - 1 = {e} * {d} - 1 = {ed_minus_1}")
s = 0
t = ed_minus_1
while t % 2 == 0:
t //= 2
s += 1
print(f"步骤2: 将 ed - 1 分解为 2^{s} * {t} 的形式")
# 随机选择一个数a,使得 2 <= a <= n-1
attempts = 0
max_attempts = 100 #limit
while attempts < max_attempts:
a = random.randint(2, n - 1)
print(f"\n尝试 #{attempts + 1}: 选择 a = {a}")
g = gcd(a, n)
if g > 1:
print(f" 找到因子: gcd({a}, {n}) = {g}")
return g, n // g
x = power_mod(a, t, n)
print(f" 计算 x = {a}^{t} mod {n} = {x}")
#x ≡ 1 (mod n) 或 x ≡ -1 (mod n)
if x == 1 or x == n - 1:
print(f" x ≡ {x} (mod {n}), 重新选择a")
attempts += 1
continue
# 迭代计算 x 的平方,直到找到非平凡平方根或达到终止条件
found = False
for i in range(s):
x_prev = x
x = (x * x) % n
print(f" 第{i+1}次迭代: x = {x_prev}^2 mod {n} = {x}")
# 如果 x ≡ 1 (mod n) 且 x_prev ≠ 1, n-1,则找到了非平凡平方根
if x == 1 and x_prev != 1 and x_prev != n - 1:
print(f" 找到非平凡平方根: {x_prev}^2 ≡ 1 (mod {n})")
# 计算 gcd(x_prev - 1, n) 和 gcd(x_prev + 1, n)
factor1 = gcd(x_prev - 1, n)
factor2 = gcd(x_prev + 1, n)
print(f" 计算 gcd({x_prev} - 1, {n}) = gcd({x_prev - 1}, {n}) = {factor1}")
print(f" 计算 gcd({x_prev} + 1, {n}) = gcd({x_prev + 1}, {n}) = {factor2}")
if factor1 > 1 and factor1 < n:
print(f" 找到因子: p = {factor1}, q = {n // factor1}")
return factor1, n // factor1
elif factor2 > 1 and factor2 < n:
print(f" 找到因子: p = {factor2}, q = {n // factor2}")
return factor2, n // factor2
else:
print(" 没有找到非平凡因子,继续尝试")
found = True
break
elif x == n - 1:
print(f" x ≡ -1 (mod {n}), 重新选择a")
break
if found:
break
attempts += 1
print(f"经过{max_attempts}次尝试后未能分解n")
return None
def verify_rsa_factors(n, e, d, p, q):
print(f"\n验证分解结果:")
print(f"n = {n}")
print(f"p = {p}")
print(f"q = {q}")
print(f"p * q = {p * q}")
if p * q == n:
print("验证通过")
else:
print("验证失败")
return False
phi = (p - 1) * (q - 1)
print(f"φ(n) = ({p} - 1) * ({q} - 1) = {phi}")
if (e * d) % phi == 1:
print(f"验证通过: {e} * {d} = {(e * d)}, ({e * d}) mod {phi} = {(e * d) % phi}")
else:
print(f"验证失败: {e} * {d} = {(e * d)}, ({e * d}) mod {phi} = {(e * d) % phi}")
return False
return True
def main():
print("RSA分解算法 - 已知解密指数d和公钥(n, e)分解n")
p1, q1 = 61, 53
n1 = p1 * q1
phi1 = (p1 - 1) * (q1 - 1)
e1 = 17
d1 = mod_inverse(e1, phi1)
print(f"原始参数: p = {p1}, q = {q1}, n = {n1}, e = {e1}, d = {d1}")
result1 = factorize_with_d(n1, e1, d1)
if result1:
p_found, q_found = result1
verify_rsa_factors(n1, e1, d1, p_found, q_found)
else:
print("分解失败")
try:
n = int(input("RSA模数n: "))
e = int(input("公钥指数e: "))
d = int(input("解密指数d: "))
print(f"\n输入参数: n = {n}, e = {e}, d = {d}")
result2 = factorize_with_d(n, e, d)
if result2:
p_found, q_found = result2
success = verify_rsa_factors(n, e, d, p_found, q_found)
if success:
print(f"\n成功分解: n = {p_found} * {q_found}")
else:
print("\n分解结果验证失败")
else:
print("分解失败")
except ValueError:
print("输入格式错误,请输入有效的整数")
except KeyboardInterrupt:
pass

浙公网安备 33010602011771号