NewStarCTF-WEEK1CRYPTO-RSA_begin题与解

NewStarCTF-WEEK1|CRYPTO-RSA_begin题与解

level-1

# Try to implement your RSA with primes p and q
def level1(message):
    m = bytes_to_long(message)
    p = getPrime(512)
    q = getPrime(512)
    n = p * q
    e = 0x10001
    assert m < n
    c = pow(m, e, n)
    print(f'c = {c}')
    print(f'p = {p}')
    print(f'q = {q}')
Level 1:
c = 22160015525054597533062795679117215923801827397299805735087138192137742945881204146337349060934854888054628153923021387981306839951210090523829296521835965212118849043671673133979884712755090374758002677916820953359774554825569218497687506468472278309097929775388010403607769802840990547048001743970754496905
p = 6962443023774446497102092246794613339314677593117417573764609329949026862782472380488956732038459060928443992561763464365758383525259954798321350043810351
q = 9631855759661411029901156175243744760977799976661519182223576693685069000499866459636568713055906075171480855575061732016121299027658733834671035383233163

这个略了,就是普通的rsa,走流程就可以做出来了。

level-2

# But how can we attack the RSA when we didn't know the primes?
def level2(message):
    m = bytes_to_long(message)
    p = getPrime(64)
    q = getPrime(64)
    n = p * q
    e = 0x10001
    assert m < n
    c = pow(m, e, n)
    print(f'c = {c}')
    print(f'n = {n}')
Level 2:
c = 17250922799297131008803303235771955129
n = 134097988095851988085603926250918812377

很明显n比较小,可以利用工具暴力分解得到p和q。

我用的是这个。

然后和上题一样,走正常流程。

import gmpy2
from Crypto.Util.number import *
c = 17250922799297131008803303235771955129
p = 10094271714305059493
q = 13284562957208247589
e = 0x10001
n=p*q
fn=(p-1)*(q-1)
d=gmpy2.invert(e,fn)
m=pow(c,d,n)
flag=long_to_bytes(m)
print(flag)

level-3

# Different e may cause danger?
def level3(message):
    m = bytes_to_long(message)
    p = getPrime(512)
    q = getPrime(512)
    e = 3
    n = p * q
    assert m < n
    c = pow(m, e, n)
    print(f'c = {c}')
    print(f'n = {n}')
Level 3:
c = 2776571135646565181849912433877522437622755332262910824866791711
n = 85793694792655420934945863688968944466300304898903354212780512650924132933351787673979641944071634528676901506049360194331553838080226562532784448832916022442020751986591703547743056267118831445759258041047213294368605599719242059474324548598203039032847591828382166845797857139844445858881218318006747115157

低加密质数攻击

from Crypto.Util.number import *
import gmpy2
import binascii

c = 2776571135646565181849912433877522437622755332262910824866791711
n = 85793694792655420934945863688968944466300304898903354212780512650924132933351787673979641944071634528676901506049360194331553838080226562532784448832916022442020751986591703547743056267118831445759258041047213294368605599719242059474324548598203039032847591828382166845797857139844445858881218318006747115157
e = 3
i = 0
while True:
    if gmpy2.iroot((c+i*n),e)[1] == True:
        m = gmpy2.iroot((c+i*n),e)[0]
        break
    i += 1

print(binascii.unhexlify(hex(m)[2:]))

level-4

# So is there anything wrong with RSA as shown below?
def level4(message):
    m = bytes_to_long(message)
    p = getPrime(512)
    q = getPrime(512)
    d = getPrime(64)
    e = inverse(d, (p-1) * (q-1))
    n = p * q
    assert m < n
    c = pow(m, e, n)
    print(f'c = {c}')
    print(f'e = {e}')
    print(f'n = {n}')
Level 4:
c = 68588738085497640698861260094482876262596289469248772328560280530093163764972313090939471997156632421517452790632223565521726590730640805290182026911025142051864898712501214753986865172996090706657535814234291235489829621372021092488300236623525366939477695283380634188510950335639019458758643273802572617191
e = 51999725233581619348238930320668315462087635295211755849675812266270026439521805156908952855288255992098479180003264827305694330542325533165867427898010879823017054891520626992724274019277478717788189662456052796449734904215067032681345261878977193341769514961038309763898052908572726913209883965288047452751
n = 68816697240190744603903822351423855593899797203703723038363240057913366227564780805815565183450516726498872118491739132110437976570592602837245705802946829337567674506561850972973663435358068441037127926802688722648016352967768929007662772115485020718202683004813042834036078650571763978066558718285783045969

维纳攻击,我直接抄了网络上的模板,可是这个模板的来源我忘记记录了,这会儿找不到了。如果出问题的话请跟我说,我紫菜,我谢罪。

#推荐模版
from __future__ import print_function
import libnum
 
def continued_fractions_expansion(numerator,denominator):#(e,N)
	result=[]
 
	divident = numerator % denominator
	quotient = numerator //denominator
	result.append(quotient)
 
	while divident != 0:
		numerator = numerator - quotient * denominator
 
		tmp = denominator
		denominator = numerator
		numerator = tmp
 
		divident = numerator % denominator
		quotient = numerator //denominator
		result.append(quotient)
 
	return result
 
def convergents(expansion):
	convergents=[(expansion[0], 1)]
	for i in range(1, len(expansion)):
		numerator = 1
		denominator = expansion[i]
		for j in range(i - 1, -1, -1):
			numerator += expansion[j] * denominator
			if j==0:
				break
			tmp = denominator
			denominator = numerator
			numerator = tmp
		convergents.append((numerator, denominator)) #(k,d)
	return convergents
 
def newtonSqrt(n):
	approx = n // 2
	better = (approx + n //approx) // 2
	while better != approx:
	    approx = better
	    better = (approx + n // approx) // 2
	return approx
 
def wiener_attack(cons, e, N):
	for cs in cons:
		k,d = cs
		if k == 0:
			continue
		phi_N = (e * d - 1) // k
		#x**2 - ((N - phi_N) + 1) * x + N = 0
		a = 1
		b = -((N - phi_N) + 1)
		c = N
		delta = b * b - 4 * a * c
		if delta <= 0:
			continue
		x1 = (newtonSqrt(delta) - b)//(2 * a)
		x2 = -(newtonSqrt(delta) + b)//(2 * a)
		if x1 * x2 == N:
			return [x1, x2, k, d]
 
 
if __name__ == "__main__":
   
    c = 68588738085497640698861260094482876262596289469248772328560280530093163764972313090939471997156632421517452790632223565521726590730640805290182026911025142051864898712501214753986865172996090706657535814234291235489829621372021092488300236623525366939477695283380634188510950335639019458758643273802572617191
    e = 51999725233581619348238930320668315462087635295211755849675812266270026439521805156908952855288255992098479180003264827305694330542325533165867427898010879823017054891520626992724274019277478717788189662456052796449734904215067032681345261878977193341769514961038309763898052908572726913209883965288047452751
    n = 68816697240190744603903822351423855593899797203703723038363240057913366227564780805815565183450516726498872118491739132110437976570592602837245705802946829337567674506561850972973663435358068441037127926802688722648016352967768929007662772115485020718202683004813042834036078650571763978066558718285783045969

    expansion = continued_fractions_expansion(e, n)
    cons = convergents(expansion)
    p, q, k, d = wiener_attack(cons, e, n)
    m = pow(c, d, n)
    print(libnum.n2s(m))

level-5

# What about different n? Just have a try with the hint!
def level5(message):
    m = bytes_to_long(message)
    p = getPrime(512)
    q = getPrime(512)
    n = p * p * q
    e = 0x10001
    d = inverse(e, p * (p-1) * (q-1))
    assert m < n
    c = pow(m, e, n)
    hint = pow(d, e, n)
    print(f'c = {c}')
    print(f'hint = {hint}')
    print(f'n = {n}')

这道题目的hint很神奇。反正在此之前我似乎没有看到过类似的题目。
d e = h i n t + k 1 ∗ p d^e=hint+k1*p de=hint+k1p

d ∗ e = 1 + k 2 ∗ p d*e=1+k2*p de=1+k2p

可以得到如下推导:

(由同余的性质可知)
( d ∗ e ) e = 1 + k 3 ∗ p (d*e)^e=1+k3*p (de)e=1+k3p

( d ∗ e ) e = h i n t ∗ e e + k 4 ∗ p (d*e)^e=hint*e^e+k4*p (de)e=hintee+k4p


h i n t ∗ e e − 1 = k 5 ∗ p hint*e^e-1=k5*p hintee1=k5p
如此可知第二个包含p为因子的数字,因此p可以计算出:
p = g c d ( h i n t ∗ e e − 1 , n ) p=gcd(hint*e^e-1,n) p=gcd(hintee1,n)
往下就很好做了,直接贴自己的代码。

from Crypto.Util.number import *
import gmpy2
c = 1135954814335407362237156338232840769700916726653557860319741136149066730262056907097728029957898420630256832277578506404721904131425822963948589774909272408535427656986176833063600681390871582834223748797942203560505159946141171210061405977060061656807175913366911284450695116982731157917343650021723054666494528470413522258995220648163505549701953152705111304471498547618002847587649651689203632845303117282630095814054989963116013144483037051076441508388998829
hint = 611144874477135520868450203622074557606421849009025270666985817360484127602945558050689975570970227439583312738313767886380304814871432558985582586031211416586296452510050692235459883608453661597776103386009579351911278185434163016083552988251266501525188362673472772346212970459561496301631587043106524741903627979311997541301471894670374945556313285203740782346029579923650160327646876967315182335114575921178144825057359851607166387868294019144940296084605930
n = 1232865496850144050320992645475166723525103370117149219196294373695624167653495180701004894188767069545579706264513808335877905149818445940067870026924895990672091745229251935876434509430457142930654307044403355838663341948471348893414890261787326255632362887647279204029327042915224570484394917295606592360109952538313570951448278525753313335289675455996833500751672463525151201002407861423542656805624090223118747404488579783372944593022796321473618301206064979
e = 0x10001
p=gmpy2.gcd(hint*e**e-1,n)
q=n//(p*p)
d = inverse(e, p * (p-1) * (q-1))
m=pow(c,d,n)
print(long_to_bytes(m))

得到结果:

flag{W0w_U_ar3_re4L1y_g0Od_4t_m4th_4nD_RSA!!}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值