DASCTF,网鼎杯部分题目复现

2020 网鼎杯 you_raise_me_up

题目代码很简单

from Crypto.Util.number import *
import random

n = 2 ** 512
m = random.randint(2, n-1) | 1
c = pow(m, bytes_to_long(flag), n)
print 'm = ' + str(m)
print 'c = ' + str(c)

m = 391190709124527428959489662565274039318305952172936859403855079581402770986890308469084735451207885386318986881041563704825943945069343345307381099559075
c = 6665851394203214245856789450723658632520816791621796775909766895233000234023642878786025644953797995373211308485605397024123180085924117610802485972584499

这里用到sage
DASCTF,网鼎杯部分题目复现_第1张图片
DASCTF,网鼎杯部分题目复现_第2张图片
直接求出了flag

DASCTF 2020 四月春季赛 not_RSA

from Crypto.Util.number import getPrime as getprime ,long_to_bytes,bytes_to_long,inverse
from secret import flag,p,q
from sympy import isprime,nextprime
import random

m=bytes_to_long(flag)
n=p*q
g=n+1
r=random.randint(1,n)

c=(pow(g,m,n*n)*pow(r,n,n*n))%(n*n)

print "c=%d"%(c)
print "n=%d"%(n)

'''
c=29088911054711509252215615231015162998042579425917914434962376243477176757448053722602422672251758332052330100944900171067962180230120924963561223495629695702541446456981441239486190458125750543542379899722558637306740763104274377031599875275807723323394379557227060332005571272240560453811389162371812183549
n=6401013954612445818165507289870580041358569258817613282142852881965884799988941535910939664068503367303343695466899335792545332690862283029809823423608093
'''

题目中说出不是RSA,可以来分析一下题目,r是由random.randint(1,n)产生的1到n的一个整数随机数,再看加密方式,c是通过两个pow函数乘积再对n的平方取余。
经过后来的查找资料才知道是Paillier cryptosystem(Paillier 密码系统)相关文章
DASCTF,网鼎杯部分题目复现_第3张图片
这里要求r和n是互质,即gcd(r,n)=1,可以验证一下r,发现符合算法要求,按照解密编写脚本。
DASCTF,网鼎杯部分题目复现_第4张图片
使用yafu分解一下n
DASCTF,网鼎杯部分题目复现_第5张图片
得到p、q等长,则可以使用变体 λ = φ(n),μ = φ(n)-1 mod n 即求φ(n)模n的乘法逆元,φ(n) = (p-1)(q-1)
套入公式,写出解题脚本

from Crypto.Util.number import long_to_bytes,bytes_to_long
import gmpy2

p = gmpy2.mpz(80006336965345725157774618059504992841841040207998249416678435780577798937819)
q = gmpy2.mpz(80006336965345725157774618059504992841841040207998249416678435780577798937447)
n = gmpy2.mpz(6401013954612445818165507289870580041358569258817613282142852881965884799988941535910939664068503367303343695466899335792545332690862283029809823423608093)
c = gmpy2.mpz(29088911054711509252215615231015162998042579425917914434962376243477176757448053722602422672251758332052330100944900171067962180230120924963561223495629695702541446456981441239486190458125750543542379899722558637306740763104274377031599875275807723323394379557227060332005571272240560453811389162371812183549)

phi = (p-1)*(q-1)
u = gmpy2.invert(phi,n)

def L(x):
	return (x-1)//n

b = gmpy2.powmod(c,phi,n*n)

m = (L(b)*u) % n
flag = long_to_bytes(m)

print(flag)

得到flag
在这里插入图片描述

你可能感兴趣的:(DASCTF,网鼎杯部分题目复现)