baigeiRSA2
题目描述
import libnum
from Crypto.Util import number
from functools import reduce
from secret import flag
n = 5
size = 64
while True:
ps = [number.getPrime(size) for _ in range(n)]
if len(set(ps)) == n:
break
e = 65537
n = reduce(lambda x, y: x*y, ps)
m = libnum.s2n(flag)
c = pow(m, e, n)
print('n = %d' % n)
print('c = %d' % c)
n = 175797137276517400024170861198192089021253920489351812147043687817076482376379806063372376015921
c = 144009221781172353636339988896910912047726260759108847257566019412382083853598735817869933202168
分析解密
- 模数N不大,对其尝试分解,得到5个因子(P1,P2,P3,P4,P5)
- 题目中while循环生成了一个五元组ps
- n = reduce(lambda x, y: x*y, ps)
- reduce(function,iterable)对参数iterable进行function累积操作
- lambda匿名函数,在 lambda 关键字之后、冒号左边为参数列表,可不带参数,也可有多个参数。若有多个参数,则参数间用逗号隔开,冒号右边为 lambda 表达式的返回值。
- 因此n为ps里面元素的乘积,即 n = p s [ 1 ] ∗ p s [ 2 ] ∗ p s [ 3 ] ∗ p s [ 4 ] ∗ p s [ 5 ] = P 1 ∗ P 2 ∗ P 3 ∗ P 4 ∗ P 5 n=ps[1]*ps[2]*ps[3]*ps[4]*ps[5]=P1*P2*P3*P4*P5 n=ps[1]∗ps[2]∗ps[3]∗ps[4]∗ps[5]=P1∗P2∗P3∗P4∗P5
- 计算欧拉函数φ(n):
欧拉函数 φ(n) 的定义是小于等于 n 的正整数中与 n 互素的数的个数。
积的欧拉函数等于各个因子的欧拉函数之积。比如,φ(56)=φ(8×7)=φ(8)×φ(7)=4×6=24
因此此题中,根据因子都是素数,有
φ(n)=φ(P1*P2*P3*P4*P5)=φ(P1)*φ(P2)*φ(P3)*φ(P4)*φ(P5)=(P1-1)*(P2-1)*(P3-1)*(P4-1)*(P5-1)
- 得到 φ(n) 后,即可计算私钥d,进行解密:
d和e在模数φ(n)下互为逆元:d = gmpy2.invert(e,phi)
m = c d m o d n c^d mod n cdmodn = pow(c,d,n) - 最后将明文m转换为字符串 libnum.n2s(int(m))
脚本如下
import gmpy2
import libnum
n = 175797137276517400024170861198192089021253920489351812147043687817076482376379806063372376015921
c = 144009221781172353636339988896910912047726260759108847257566019412382083853598735817869933202168
e = 65537
'''
循环生成了一个五元组ps
n = reduce(lambda x, y: x*y, ps)
reduce(function,iterable)对参数iterable进行function累积操作
lambda匿名函数,在 lambda 关键字之后、冒号左边为参数列表,可不带参数,也可有多个参数。若有多个参数,则参数间用逗号隔开,冒号右边为 lambda 表达式的返回值。
因此n为ps里面元素的乘积
'''
#分解n有:
P1 = 9401433281508038261
P2 = 13716847112310466417
P3 = 11215197893925590897
P4 = 10252499084912054759
P5 = 11855687732085186571
#求欧拉函数φ(n)
#欧拉函数 φ(n) 的定义是小于等于 n 的正整数中与 n 互素的数的个数。
#积的欧拉函数等于各个因子的欧拉函数之积。比如,φ(56)=φ(8×7)=φ(8)×φ(7)=4×6=24
#因此此题中φ(n)=φ(P1*P2*P3*P4*P5)=φ(P1)*φ(P2)*φ(P3)*φ(P4)*φ(P5)=(P1-1)*(P2-1)*(P3-1)*(P4-1)*(P5-1),因子都是素数
phi = (P1-1)*(P2-1)*(P3-1)*(P4-1)*(P5-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(libnum.n2s(int(m)))
#b'HSCTF{@Tv0_br3ad5_c1ip_cHe3se_!@}'
cr4-poor-rsa
题目描述
文件下载下来是一个.gz的压缩包,用Bandizip打开里面是密钥文件key.pub和flag文件flag.b64
!注意:不能就这样直接提取文件出来,得到的flag文件内容可能会出错。
正确的方式是将.gz补全后缀名,修改为.gz.tar压缩包,然后解压文件。
分析解密
- 对密钥pub文件提取n和e
哈哈我也不会,找了一下怎么打开key.pub文件
参考链接:https://blog.csdn.net/ChaoYue_miku/article/details/125749442
from Crypto.PublicKey import RSA
#获取密钥文件中的n和e
with open("./key.pub","rb") as file:
key = file.read()
pub = RSA.importKey(key)
n = pub.n
e = pub.e
print("n=",n)
print("e=",e)
- 提取出n,e后,分解n得到p,q,然后可以计算私钥d
d = gmpy2.invert(e,(p-1)*(q-1)) - 提取密文后,解密flag:
生成私钥priv:rsa.PrivateKey(n,e,d,p,q)
先base64解密:base64.b64decode(cipher)
再rsa解密:rsa.decrypt(c,priv)
脚本如下:
from Crypto.PublicKey import RSA
import gmpy2
import base64
import rsa
#获取密钥文件中的n和e
with open("./key.pub","rb") as file:
key = file.read()
pub = RSA.importKey(key)
n = pub.n
e = pub.e
print("n=",n)
print("e=",e)
'''
#n= 833810193564967701912362955539789451139872863794534923259743419423089229206473091408403560311191545764221310666338878019
#e= 65537
'''
#分解n,计算d
p = 863653476616376575308866344984576466644942572246900013156919
q = 965445304326998194798282228842484732438457170595999523426901
d = gmpy2.invert(e,(p-1)*(q-1))
print("d=",d)
'''
根据n,e,d,p,q生成私钥,进行解密
先base64解密,再rsa解密
'''
priv = rsa.PrivateKey(n,e,d,p,q) #生成私钥
with open("./flag.b64","rb") as file: #提取密文cipher
cipher = file.read()
print("cipher=",cipher)
c = base64.b64decode(cipher) #base64解密
flag = rsa.decrypt(c,priv).decode() #rsa解密
print("flag=",flag)
#flag= ALEXCTF{SMALL_PRIMES_ARE_BAD}