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
直接求出了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 密码系统)相关文章
这里要求r和n是互质,即gcd(r,n)=1,可以验证一下r,发现符合算法要求,按照解密编写脚本。
使用yafu分解一下n
得到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