Wener‘s attack(RSA低解密指数攻击)

参考文章

Wiener’s attack
Crypto Classics: Wiener’s RSA Attack
中文参考1
中文参考2

Wener’s attack

重点知识:

连分数、渐进分数。
连分数
举个例子比较清晰,如图
在这里插入图片描述
那么e/N的依次每个渐进分数
在这里插入图片描述

描述:

Wiener 表示如果满足:d<(1/3)* n **(1/4)
那么一种基于连分数(一个数论当中的问题)的特殊攻击类型就可以危害 RSA 的安全。

思路如下:

在RSA中有式子:ed = 1%n 推到公式变换为:
**e/phi -k/d = 1/(d
phi)**
因为p,q很大有phi接近与n e/n -k/d = 1/(d*n)
又因为d * n很大所以有e/n接近于k/d (e/n略大于k/d)
计算e/n的连分数展开,依次算出每一个渐进分数。因为e/n > k/d 所以e/n 的渐进分数覆盖了k/d。也就是说e/n的渐进分数里有等于k/d的分数。接着验证k,d是否满足条件。

算法过程:
  1. 通过对e/n进行连分数展开
  2. 然后依次求其渐进分数
  3. 遍历所有渐进分数如果找到了d的话,(ed-1)会整除phi,也就是存在k使得(ed-1)//k=phi,建立方程求p,q。( x2−(p+q)∗x+pq=0这个方程的解就是p,q)如果p*q==n则找到了d
搬运代码:

理解最重要!!!

import gmpy2

# numerator(n):分子, denominator(d):分母
def t_cf(n, d):  # 将分数 x/y 转为连分数的形式
    res = []
    while d:
        res.append(n // d)
        n, d = d, n % d
    return res


def cf(sub_res):    # 得到渐进分数的分母和分子
    n, d = 1, 0
    for i in sub_res[::-1]:  # 从后面往前循环
        d, n = n, i * n + d
    return d, n


def list_fraction(x, y):     # 列出每个渐进分数
    res = t_cf(x, y)
    res = list(map(cf, (res[0:i] for i in range(1, len(res)))))  # 将连分数的结果逐一截取以求渐进分数
    return res


def get_pq(a, b, c):  # 由p+q和pq的值通过维达定理来求解p和q(解二元一次方程)
    par = gmpy2.isqrt(b * b - 4 * a * c)  # 由上述可得,开根号一定是整数,因为有解
    x1, x2 = (-b + par) // (2 * a), (-b - par) // (2 * a)
    return x1, x2


def wienerAttack(e, n):
    for (d, k) in list_fraction(e, n):  # 用一个for循环来注意试探e/n的连续函数的渐进分数,直到找到一个满足条件的渐进分数
        if k == 0:  # 可能会出现连分数的第一个为0的情况,排除
            continue
        if (e * d - 1) % k != 0:  # ed=1 (mod φ(n)) 因此如果找到了d的话,(ed-1)会整除φ(n),也就是存在k使得(e*d-1)//k=φ(n)
            continue

        phi = (e * d - 1) // k  # 这个结果就是 φ(n)
       
        px, qy = get_pq(1, n - phi + 1, n)

        if px * qy == n:
            p, q = abs(int(px)), abs(int(qy))  # 可能会得到两个负数,负负得正未尝不会出现
            d = gmpy2.invert(e, (p - 1) * (q - 1))  # 求ed=1 (mod  φ(n))的结果,也就是e关于 φ(n)的乘法逆元d
            return d
    print("求解d失败")

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值