1004BUUCTF-CRYPTO-[HDCTF2019]basic rsa-NOTES

题目

python 复制代码
import gmpy2
from Crypto.Util.number import *
from binascii import a2b_hex,b2a_hex

flag = "*****************"

p = 262248800182277040650192055439906580479
q = 262854994239322828547925595487519915551

e = 65533
n = p*q


c = pow(int(b2a_hex(flag),16),e,n)

print c

# 27565231154623519221597938803435789010285480123476977081867877272451638645710

这段代码是一个 RSA 加密脚本,它的作用是:

  • flag(比如 "flag{...}")转换成一个大整数;
  • 用 RSA 公钥 (e, n) 对它加密;
  • 输出密文 c

而你看到的这些 import 语句,就是为了让 Python 能完成这些数学和编码操作而引入的"工具包"。


🔧 第一行:import gmpy2
✅ 是什么?

gmpy2 是一个 高性能的 Python 数学库,专门用于处理:

  • 大整数(比如几百位的数字)
  • 高精度浮点数
  • 快速的数论运算(比如求逆元、模幂、判断质数等)

✅ 有什么用?(在本题中)

虽然这段加密代码没有直接使用 gmpy2(它只用了 pow),但在解密时(也就是你作为 CTF 选手要做的事),你会用到它,比如:

复制代码

Python

编辑

复制代码
d = gmpy2.invert(e, phi)  # 求 e 在模 phi 下的逆元(即私钥 d)

或者:

复制代码

Python

编辑

复制代码
root = gmpy2.iroot(c, e)  # 尝试开 e 次方根(当 n 很大但 e 很小时)

💡 所以:出题人提前导入了 gmpy2,暗示你解题时可能需要用到它(即使加密过程没用)。


🔧 第二行:from Crypto.Util.number import *

✅ 是什么?

这是从 PyCryptodome (一个流行的密码学库)中导入一系列和数字、RSA 相关的实用函数

import * 的意思是:把 Crypto.Util.number 里的所有常用函数都直接拿来用,不用加前缀。

✅ 常见导入的函数包括(你可能用到的):

函数 作用
getPrime(bits) 生成一个指定位数的质数(比如 getPrime(1024)
inverse(a, n) 计算 a 在模 n 下的逆元(类似 gmpy2.invert
long_to_bytes(x) 把大整数 x 转成字节(比如把解密出的数字变回 "flag{...}"
bytes_to_long(b) 把字节(如 b"hello")转成大整数
isPrime(n) 判断 n 是否为质数

✅ 在本题中的作用?

虽然加密代码没显式调用这些函数,但:

  • flag 被转成十六进制再转整数,其实可以用 bytes_to_long(flag.encode()) 更直接;
  • 你解密时一定会用 long_to_bytes(m) 把解出的数字 m 变回字符串!

🌰 举例:

如果你算出明文整数 m = 123456...

long_to_bytes(m) 就能得到 b'flag{...}'


🔧 第三行:from binascii import a2b_hex, b2a_hex

✅ 是什么?

binascii 是 Python 内置模块,用于在 二进制数据ASCII 编码的十六进制字符串 之间转换。

  • b2a_hex(data):把字节(bytes)转成十六进制字符串(bytes to ASCII hex
    • 例如:b2a_hex(b"AB")b'4142'(因为 'A'=0x41, 'B'=0x42)
  • a2b_hex(hexstr):把十六进制字符串转回字节(ASCII hex to bytes
    • 例如:a2b_hex(b'4142')b'AB'

⚠️ 注意:它们的输入输出都是 bytes 类型,不是普通字符串。

✅ 在本题中怎么用?

看这行关键代码:

复制代码

Python

编辑

复制代码
c = pow(int(b2a_hex(flag), 16), e, n)

我们一步步拆解:

  1. flag 是字符串,比如 "flag{test}"
  2. b2a_hex 需要 bytes ,所以实际应为 flag.encode()(但题目没写,可能是简化或假设 flag 已是 bytes)
    • 正确写法通常是:b2a_hex(flag.encode())
  3. b2a_hex(flag) → 得到十六进制的 bytes,比如 b'666c61677b746573747d'
  4. int(..., 16) → 把这个十六进制字符串当作 16 进制数 ,转成一个大整数
    • 例如:int('666c...', 16) → 一个很大的整数 m
  5. pow(m, e, n) → 计算 m^e mod n,得到密文 c

✅ 所以:b2a_hex 的作用是 把 flag 字符串变成一个可以用于 RSA 加密的大整数


🧩 总结:每个 import 的作用

代码 作用 为什么需要?
import gmpy2 高性能大数运算 解密时求逆元、开根等(虽然加密没用,但暗示解题方向)
from Crypto.Util.number import * 密码学常用数字工具 解密后把整数转回字符串(long_to_bytes),或处理大数
from binascii import a2b_hex, b2a_hex 字节 ↔ 十六进制转换 flag 字符串编码成整数 m,以便 RSA 加密

💡 给初学者的建议

  1. 不要怕 import:它们只是"借工具",就像做饭前先拿锅、刀、铲。
  2. gmpy2Crypto.Util.number 是 CTF RSA 题的标配,一定要会用。
  3. 字符串 → 整数 → 加密 → 解密 → 整数 → 字符串 是标准流程,b2a_hex/long_to_bytes 就是桥梁。

✅ 举个完整例子(你解密时会写的代码):

复制代码

Python

编辑

复制代码
from Crypto.Util.number import long_to_bytes
import gmpy2

# 已知 p, q, e, c
phi = (p-1)*(q-1)
d = int(gmpy2.invert(e, phi))  # 求私钥
m = pow(c, d, n)               # 解密
flag = long_to_bytes(m)        # 变回字符串!
print(flag)

这样你就把密文 c 变回了 flag{...}

相关推荐
我命由我123452 小时前
Git 暂存文件警告信息:warning: LF will be replaced by CRLF in XXX.java.
java·linux·笔记·git·后端·学习·java-ee
lingggggaaaa3 小时前
小迪安全v2023学习笔记(九十五讲)—— 云原生篇&Docker安全&权限环境检测&容器逃逸&特权模式&危险挂载
笔记·学习·安全·web安全·网络安全·docker·云原生
聪明的笨猪猪3 小时前
Java 内存模型(JMM)面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
想唱rap4 小时前
Linux指令(1)
linux·运维·服务器·笔记·新浪微博
东方芷兰5 小时前
LLM 笔记 —— 02 大语言模型能力评定
人工智能·笔记·python·神经网络·语言模型·自然语言处理·cnn
71-37 小时前
C语言——循环的嵌套小练习
c语言·笔记·学习·其他
东方芷兰7 小时前
LLM 笔记 —— 03 大语言模型安全性评定
人工智能·笔记·python·语言模型·自然语言处理·nlp·gpt-3
悠哉悠哉愿意8 小时前
【ROS2学习笔记】Gazebo 仿真与 XACRO 模型
笔记·学习·机器人·ros2
悠哉悠哉愿意8 小时前
【ROS2学习笔记】节点篇:ROS 2编程基础
笔记·学习·ros2