安恒四月赛 not rsa

安恒四月赛的一道crypto题。

下载附件得:

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
'''

分析一下。

从 secret 导入flag,p,q的值,flag经bytes_to_long处理转换为长整数传递给m,n为p,q乘积,g的值为n+1,r是由random.randint(1,n)产生的 1 到 n 的一个整数型随机数。

再看c的等式,对于pow()函数,pow(x,y,z)表示x的y次幂除以z的余数,即等价于x**y%z,即c的值经过两个pow函数的乘积再对n的平方取余。

最后是打印出c,n的值,且下方已给出。

题目明确说了不是RSA,看了半天也没看出来这是个什么算法,后来才知道是Paillier_cryptosystem,得知加密方式为:

安恒四月赛 not rsa_第1张图片

可以看到c的等式符合,再验证一下r:

import random
from math import gcd


n=6401013954612445818165507289870580041358569258817613282142852881965884799988941535910939664068503367303343695466899335792545332690862283029809823423608093

r=random.randint(1,n)
if gcd(r,n)==1:
    print('right')

在这里插入图片描述
符合加密方式。接下来按照解密方式编写脚本即可:
安恒四月赛 not rsa_第2张图片
嗯。。。这里又看懵了,继续找资料,在wiki上找到:

  • L(x)=(x−1)/n
  • 本题p,q的长度相等,λ,μ的值如下:

在这里插入图片描述

好的一步一步来,首先分解n,这里用yafu很快就算出来了(factordb无效,再次吐槽):

安恒四月赛 not rsa_第3张图片

然后尝试套用公式写脚本

from Crypto.Util.number import long_to_bytes
from gmpy2 import powmod,invert


p = 80006336965345725157774618059504992841841040207998249416678435780577798937819
q = 80006336965345725157774618059504992841841040207998249416678435780577798937447
n=6401013954612445818165507289870580041358569258817613282142852881965884799988941535910939664068503367303343695466899335792545332690862283029809823423608093
c=29088911054711509252215615231015162998042579425917914434962376243477176757448053722602422672251758332052330100944900171067962180230120924963561223495629695702541446456981441239486190458125750543542379899722558637306740763104274377031599875275807723323394379557227060332005571272240560453811389162371812183549

phi = (p-1)*(q-1) 
lamuda = phi 
mo = powmod(c,lamuda,n*n) #快速幂取模方法
miu = invert(lamuda,n) 

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

m = L(mo)
fina = (m*miu)%n

flag = long_to_bytes(fina)

print(flag)

得到flag:

在这里插入图片描述

你可能感兴趣的:(crypto)