NSSCTF_crypto_[SWPUCTF 2022 新生赛]小明文
提示:小明文攻击
题目:
from gmpy2 import invert
from Crypto.Util.number import getPrime, bytes_to_long
from flag import getflag
e = 3
p = getPrime(1024)
q = getPrime(1024)
n = p * q
phiN = (p - 1) * (q - 1)
d = invert(e, phiN)
m = bytes_to_long(getflag().encode())
c = pow(m, e, n)
print("c=" + str(c))
#c=128198926274489803523728445192921664
#flag=NSSCTF{c}
攻击原理
低加密指数攻击(小明文攻击)
当RSA加密满足以下条件时:
-
加密指数
e
很小(通常e=3
或e=5
) -
明文
m
很小,使得m^e < n
(即加密时未发生模运算)
此时密文 c = m^e
(没有模 n
),可以直接对 c
开 e
次方恢复明文。
解题步骤
-
识别攻击场景:
-
观察到密文
c
相对较小(160位) -
推测可能使用了小指数
e=3
-
验证
c
是否是完全立方数
-
-
直接计算立方根:
m = gmpy2.iroot(c, 3)[0] # 计算c的整数立方根
-
转换明文格式:
plaintext = long_to_bytes(m) # 将整数转换为字节串
完整攻击代码
from Crypto.Util.number import *
from gmpy2 import *
# 给定密文
c = 128198926274489803523728445192921664
print("[+] 正在执行低加密指数攻击...")
print(f"[+] 密文c = {c}")
# 计算立方根
m_cubed, is_perfect_cube = iroot(c, 3)
if not is_perfect_cube:
print("[-] 警告:密文不是完全立方数,攻击可能失败")
print(f"[+] 计算得到的立方根 = {m_cubed}")
# 转换为字节
try:
plaintext = long_to_bytes(m_cubed).decode()
print("[+] 解密成功!明文为:")
print("--------------------------------------------------")
print(plaintext)
print("--------------------------------------------------")
except:
print("[+] 解密得到的字节:")
print("--------------------------------------------------")
print(long_to_bytes(m_cubed))
print("--------------------------------------------------")
运行后flag为
NSSCTF{ufind}