BUU-RSA入门题

RSA

题目

在一次RSA密钥对生成中,假设p=473398607161,q=4511491,e=17
求解出d作为flag提交

解题思路

在密码学相关计算中,可利用python的gmpy2库,非常方便

附上代码:

import gmpy2
p =9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e = 65537
d = gmpy2.invert(e, (q-1)*(p-1))
print(d)

flag

flag{125631357777427553}

知识点

RSA加密

参数pqde,公开n,e,秘密保存d

  • 1.n=pq,fai(n)=(p-1)(q-1),fai()指欧拉函数
  • 2.(de)mod(fai(n)) = 1,即de = k(fai(n))+1

加密
c = m^e mod n
解密
m = c^d mod n

gmpy2库的常用函数

  • gmpy2.mpz(n)#初始化一个大整数
  • gmpy2.mpfr(x)# 初始化一个高精度浮点数x
  • d = gmpy2.invert(e,n) # 求逆元,de = 1 mod n
  • C = gmpy2.powmod(M,e,n)# 幂取模,结果是 C = (M^e) mod n
  • gmpy2.is_prime(n) #素性检测
  • gmpy2.gcd(a,b) #return r 其中,r为a和b的最大公约数
  • gmpy2.gcdext(a,b) #扩展欧几里得算法,return (r,x,y) 其中,r为a和b的最大公约数,满足ax + by = 1
  • gmpy2.iroot(x,n) #x开n次根

rsarsa

题目

Math is cool! Use the RSA algorithm to decode the secret message, c, p, q, and e are parameters for the RSA algorithm.

p = 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e = 65537
c = 83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034

Use RSA to find the secret message

解题思路

这道题是最基础的RSA题,p,q,e,c全部给出,直接计算出私钥d,再进行解密即可

其中,d为e(mod φ(n))的逆元,即d * e = 1 + k * φ(n)

gmpy2库中的gmpy2.invert()可以计算逆元

附上代码:

import gmpy2
p =9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e = 65537
n = p * q
c =  83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034

d = gmpy2.invert(e, (q-1)*(p-1))#计算逆元
m = gmpy2.powmod(c,d,n)#解密m = c^d % n
print("flag{%d}" % m)

flag

flag{5577446633554466577768879988}

RSAROLL

题目

RSA roll!roll!roll!
Only number and a-z(don’t use editorwhich MS provide)

{920139713,19}

另给出 data.txt

解题思路

{920139713,19}给出了公钥{n, e}

公钥很短,直接爆破分解就行了

这里分解的具体思路为:

  • 假设p = x + y,q = x - y,则n = p * q = x2 - y2,这里可以确定x2 > n
  • 然后直接从√n往上遍历寻找x
  • 令y = √(x2 - n)
  • 若p = x + y,q = x - y满足:n = p * q且均为素数,就证明分解成功

分解完后,计算私钥d,再对data.txt中的密文进行解密即可得到flag

附上代码:

import gmpy2
    
#因数分解,返回值分别为n的因数
def Factorization(n):
    x = gmpy2.iroot(n,2)[0] + 1 #gmpy2.iroot(x,n) #x开n次根
    while(True):
        y2 = x * x - n
        y = gmpy2.iroot(y2,2)[0]
        p, q = x + y, x - y
        if (p) * (q) == n:
            if gmpy2.is_prime(p) and gmpy2.is_prime(q): #素性检测
                return (p, q)
        x = x + 1
        
if __name__ == "__main__":
    n, e = 920139713, 19
    p, q = Factorization(n)
    print("N的分解结果为 : ")
    print("%d = %d * %d" % (n, p, q))
    d = gmpy2.invert(e,(p-1)*(q-1)) # 求私钥d,d为e的逆元
    with open("./data.txt","r") as f:
        for line in f.readlines():
            line=line.strip('\n')#去掉列表中每一个元素的换行符
            print(chr(gmpy2.powmod(int(line),d,n)), end = '')

flag

flag{13212je2ue28fy71w8u87y31r78eu1e2}

RSA(latter)

题目

这个题目名字也叫RSA,和前面那道重合了,故用(latter)加以区分

题目给出两个文件,分别是

  • flag.enc
    在这里插入图片描述
  • pub.key
    在这里插入图片描述

解题思路

这里给出的pub.key明显是一个公钥文件

放到网站上提取公钥http://tool.chacuo.net/cryptrsakeyparse,提取得到

e = 65537
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517

这是一个256bit的n,用前面的爆破代码效率很低

君子生非异也,善假于物也

因此需要用到一个分解模数的网站http://www.factordb.com,分解得到

p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463

至此,参数齐活了,然后计算私钥d进行解密即可

附上代码:

import gmpy2
import binascii

e = 65537
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463
d = gmpy2.invert(e,(p-1)*(q-1)) #求私钥d,d为e的逆元

with open("flag.enc", "rb+") as f:
    c = f.read()    #读取密文
c = int.from_bytes(c, byteorder='big', signed=False)    #byte类型数据转十进制

m = gmpy2.powmod(c,d,n) # 幂取模,求明文
m = hex(m)[2:]     
print("明文数据为:0x" + m)
flag = binascii.unhexlify('0' + m)

print(flag)

运行之后,得到b’\x02\x9d {zR\x1e\x08\xe4\xe6\x18\x06\x00flag{decrypt_256}\n’

这里有一个小坑,直接令flag = binascii.unhexlify(m)会报错,因为m是一个奇数长度的字符串,所以让它前面加了一个’0’,当然加一个’1’也是一样的。另外,不清楚为什么前面会多出一些乱码,知道的同学可以评论区解释一下。

flag

flag{decrypt_256}


版权声明:本文为xiao_han_a原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。