deftransform(x, y): # 使用辗转相处将分数 x/y 转为连分数的形式 res = [] while y: res.append(x // y) x, y = y, x % y return res
defcontinued_fraction(sub_res): numerator, denominator = 1, 0 for i in sub_res[::-1]: # 从sublist的后面往前循环 denominator, numerator = numerator, i * numerator + denominator return denominator, numerator # 得到渐进分数的分母和分子,并返回
# 求解每个渐进分数 defsub_fraction(x, y): res = transform(x, y) res = list(map(continued_fraction, (res[0:i] for i inrange(1, len(res))))) # 将连分数的结果逐一截取以求渐进分数 return res
defget_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
defwienerAttack(e, n): for (d, k) in sub_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("该方法不适用")
n = 101991809777553253470276751399264740131157682329252673501792154507006158434432009141995367241962525705950046253400188884658262496534706438791515071885860897552736656899566915731297225817250639873643376310103992170646906557242832893914902053581087502512787303322747780420210884852166586717636559058152544979471 e = 46731919563265721307105180410302518676676135509737992912625092976849075262192092549323082367518264378630543338219025744820916471913696072050291990620486581719410354385121760761374229374847695148230596005409978383369740305816082770283909611956355972181848077519920922059268376958811713365106925235218265173085 d = wienerAttack(e, n) print("d=", d) k = hex(d)[2:] flag = "NEFUCTF{" + hashlib.md5(k.encode('utf-8')).hexdigest() + "}" # flag = "NEFUCTF{" + hashlib.md5(hex(d)).hexdigest() + "}" print(flag)
# NEFUCTF{{47bf28da384590448e0b0d23909a25a4}
hard
RSA加密 pow(enc,e,N)
RSA解密 n==>p,q phi=(p-1)*(q-1) d = gmpy2.invert(e,phi) m=pow(enc,d,n)