大数跨境
0
0

密码学CTF题目-密码学RSA

密码学CTF题目-密码学RSA 豆豆咨询
2025-12-06
1
1、题目来源与分析
攻防世界-baigeiRSA2
根据以下程序和数据,解出以下题目的flag:
n=175797137276517400024170861198192089021253920489351812147043687817076482376379806063372376015921 
c=144009221781172353636339988896910912047726260759108847257566019412382083853598735817869933202168 
程序如下:

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)


分析与解答:

1、ps = [number.getPrime(size) for _ in range(n)]

number.getPrime(size)

  • number 是从 Crypto.Util 导入的模块(实际是 from Crypto.Util import number

  • getPrime(size) 是该模块的一个函数

  • 作用:生成一个随机的 size 比特的素数

  • 这里的 size = 64,所以每个素数都是 64 比特的

for _ in range(n)

  • n = 5(在程序开头定义)

  • range(5) 生成序列 [0, 1, 2, 3, 4]

  • _ 是一个惯用变量名,表示我们不需要在循环中使用这个值(只是用来重复执行 5 次)

列表推导式 [... for ...]

  • 整个结构表示:执行括号内的代码 5 次,每次生成一个 64 比特的素数,并将所有结果收集到一个列表中

if len(set(ps)) == n:

这个检查确保所有 5 个素数都是不同的

  • set(ps) 将列表转换为集合(自动去重)

  • 如果去重后的元素个数仍然是 5,说明没有重复的素数

  • 如果有重复,就重新生成(因为 while True 循环会继续)

reduce() 函数

  • 来自 from functools import reduce

  • 作用:对一个序列的所有元素累积应用某个函数

  • 格式:reduce(函数, 序列, 初始值)(初始值可选)

 lambda x, y: x*y

  • 这是一个匿名函数(lambda 函数)

  • 接受两个参数 x 和 y,返回它们的乘积 x*y

整个表达式的作用

reduce(lambda x, y: x*y, ps) 对列表 ps 中的 5 个素数执行连乘运算。

执行过程(假设 ps = [p1, p2, p3, p4, p5]):

  1. 取前两个元素:x = p1, y = p2 → p1 * p2

  2. 结果作为新的 x,下一个元素 p3 作为 y → (p1*p2) * p3

  3. 继续:((p1*p2)*p3) * p4

  4. 最后:(((p1*p2)*p3)*p4) * p5

最终得到:n = p1 × p2 × p3 × p4 × p5

libnum.s2n()

  • libnum 是一个密码学常用的 Python 库

  • s2n 代表 "string to number"(字符串转数字)

pow() 函数

Python 内置的 pow() 函数有三种形式:

  • pow(x, y):计算 x 的 y 次方

  • pow(x, y, z):计算 x 的 y 次方 对 z 取模

这里使用的是第三种形式,即模幂运算,非常适合 RSA 加密。


解题:

a. 首先获取n的质因数的乘积,程序如下:

import sympy
n =175797137276517400024170861198192089021253920489351812147043687817076482376379806063372376015921
print(sympy.factorint(n))


sympy.factorint(n)

  • sympy 是一个 Python 数学符号计算库

  • factorint() 是 SymPy 的整数分解函数

  • 作用:将整数 n 分解为质因数的乘积

函数特性

  • 返回一个字典,键是质因数,值是该质因数的指数

  • 例如:factorint(60) 返回 {2: 2, 3: 1, 5: 1},表示 60 = 2² × 3 × 5


b.然后根据质因子,获取欧拉函数phi,进而通过gmpy2.invert(e,phi),获取私钥d,最终通过power(c,d,n)获取明文。程序如下:

import gmpy2
from Crypto.Util.number import*
n=175797137276517400024170861198192089021253920489351812147043687817076482376379806063372376015921
c=144009221781172353636339988896910912047726260759108847257566019412382083853598735817869933202168
e = 65537
p1 = 9401433281508038261
p2 = 11855687732085186571
p3 = 10252499084912054759
p4 = 13716847112310466417
p5 = 11215197893925590897
phi=(p1-1)*(p2-1)*(p3-1)*(p4-1)*(p5-1)
d=gmpy2.invert(e,phi)
assert n == p1*p2*p3*p4*p5
m=pow(c,d,n)
print(long_to_bytes(m))

【声明】内容源于网络
0
0
豆豆咨询
提供前沿的信息技术咨询,实用的编程、项目管理方法,优质的专家服务,如PHP、Java、C#、C++、ASP.NET、ThinkPHP、Git、Matlab、图像处理、数据库、云计算、科技论文撰写等。
内容 44
粉丝 0
豆豆咨询 提供前沿的信息技术咨询,实用的编程、项目管理方法,优质的专家服务,如PHP、Java、C#、C++、ASP.NET、ThinkPHP、Git、Matlab、图像处理、数据库、云计算、科技论文撰写等。
总阅读33
粉丝0
内容44