crtrsa -- 2021巅峰极客

本文介绍了一种利用欧拉定理和数学技巧破解RSA加密的方法,通过穷举dp并计算gcd(n, me*dp-m)来找到素数p,从而分解大整数n。代码示例展示了如何实现这一过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2021“巅峰极客”网络安全技能挑战赛

crtrsa

题目:

from secret import flagn,p,q
#p and q are two primes generated by getPrime
import random
def key_gen():
    while True:
	dp = random.randint(1,1<<20)
	dq = random.randint(1,q-1)
	if gcd(dp, p - 1) == 1 and gcd(dq, q - 1) == 1:
	    d = crt([dp,dq],[p-1,q-1])
	    phi = (p-1)*(q-1)
	    R = Integers(phi)
	    e = R(d)^-1
	    return p*q,e
n,e = key_gen()
print e
print n
print pow(flagn,int(e),n)

'''
e = 2953544268002866703872076551930953722572317122777861299293407053391808199220655289235983088986372630141821049118015752017412642148934113723174855236142887
N = 6006128121276172470274143101473619963750725942458450119252491144009018469845917986523007748831362674341219814935241703026024431390531323127620970750816983
flag = 4082777468662493175049853412968913980472986215497247773911290709560282223053863513029985115855416847643274608394467813391117463817805000754191093158289399
'''

可以看到dp的范围是在[1,1048576],这个范围应该是可以进行穷举的。那如何利用这一点呢?

首先由以下公式和定理:
① e ∗ d ≡ 1 ( m o d   φ ( n ) ) = = > e ∗ d ≡ 1 ( m o d   ( p − 1 ) ) ) ② d p ≡ d ( m o d   ( p − 1 ) ) 欧 拉 定 理 : 设 m 是 大 于 1 的 整 数 , 如 果 a 是 满 足 ( a , m ) = 1 的 整 数 , 则 a φ ( m ) ≡ 1 ( m o d   m ) ①e*d≡1\quad (mod\ φ(n)) ==>e*d≡1\quad (mod\ (p-1)))\\ ②dp≡d\quad (mod\ (p-1))\\ 欧拉定理: \\设m是大于1的整数,如果a是满足(a,m) = 1的整数,则\\ a^{φ(m)}≡1\quad(mod\ m) ed1(mod φ(n))==>ed1(mod (p1)))dpd(mod (p1))m1a(a,m)=1aφ(m)1(mod m)
由①,②得
e ∗ d p ≡ 1 ( m o d ( p − 1 ) ) = = > e ∗ d p = 1 + k ∗ ( p − 1 ) e*dp≡1\quad(mod\quad(p-1))\\ ==> e*dp=1+k*(p-1) edp1(mod(p1))==>edp=1+k(p1)
根据欧拉定理有(m∈(1,p),p是素数,即(m,p) = 1):
m φ ( p ) ≡ m p − 1 ≡ 1 ( m o d   p ) m^{φ(p)}≡m^{p-1}≡1\quad(mod\ p) mφ(p)mp11(mod p)
进一步化简:
m p − 1 ≡ 1 ( m o d   p ) = = > m k ∗ ( p − 1 ) + 1 ≡ m ( m o d   p ) = = > m e ∗ d p ≡ m ( m o d   p ) m^{p-1} ≡ 1\quad(mod\ p) ==> m^{k*(p-1)+1} ≡ m\quad(mod\ p)==>m^{e*dp} ≡ m\quad(mod\ p) mp11(mod p)==>mk(p1)+1m(mod p)==>medpm(mod p)
所以有 p ∣ m e ∗ d p − m p|m^{e * dp} - m pmedpm,又有p|n,进一步得出 g c d ( n , m e ∗ d p − m ) = p gcd(n,m^{e * dp} - m) = p gcd(n,medpm)=p

综上:我们可以随意选取m∈(1,p),通过枚举dp,根据 p = g c d ( n , m e ∗ d p − m ) ! = 1 p = gcd(n,m^{e * dp} - m) != 1 p=gcd(n,medpm)!=1来求出p,进而分解n。

代码:

import gmpy2
from Crypto.Util.number import *

e = 2953544268002866703872076551930953722572317122777861299293407053391808199220655289235983088986372630141821049118015752017412642148934113723174855236142887
n = 6006128121276172470274143101473619963750725942458450119252491144009018469845917986523007748831362674341219814935241703026024431390531323127620970750816983
c = 4082777468662493175049853412968913980472986215497247773911290709560282223053863513029985115855416847643274608394467813391117463817805000754191093158289399
#dp = d % (p-1)     dq = d % (q-1)

m = 10000001
for dp in range(1,(1<<20)+1):
    print(dp)
    temp = pow(m,e*dp,n) - m
    p = gmpy2.gcd(n,temp)
    if p != 1:
        q = n // p
        try:
            d = gmpy2.invert(e,(p-1)*(q-1))
            flag = long_to_bytes(pow(c,d,n))
            if b'flag' in flag or b'ctf' in flag:
                print(flag)
                break
        except:
            pass
   
    
#dp = 915155
#b'flag{d67fde91-f6c0-484d-88a4-1778f7fa0c05}'

参考:
https://zhuanlan.zhihu.com/p/395205287

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值