题目:
from Crypto.Util.number import *
from secret import *
flag_part = flag_content + '#' + secret_token
p = getPrime(512)
q = getPrime(512)
m = bytes_to_long(flag_part.encode())
e = 5
n = p*q
c = pow(m,e,n)
print('n =', n)
print('c =', c)
print('flag_part =', flag_part)
print()
print('--- hint begin ---')
print('flag = "flag{" + flag_part + "}"')
print('type of secret_token is', type(secret_token))
print('length of secret_token is', len(secret_token))
# n = 131889193322687215946601811511407251196213571687093913054335139712633125177496800529685285401802802683116451016274353008428347997732857844896393358010946452397522017632024075459908859131965234835870443110233375074265933004741459359128684375786221535003839961829770182916778717973782408036072622166388614214899
# c = 11188201757361363141578235564807411583085091933389381887827791551369738717117549969067660372214366275040055647621817803877495473068767571465521881010707873686036336475554105314475193676388608812872218943728455841652208711802376453034141883236142677345880594246879967378770573385522326039206400578260353074379
# flag_part = sm4ll_r00ts_is_brilliant#◼️◼️◼️◼️◼️◼️◼️◼️
#
# --- hint begin ---
# flag = "flag{" + flag_part + "}"
# type of secret_token is <class 'str'>
# length of secret_token is 8
由题目可以看出这是一道RSA已知部分明文的高位攻击.
高位攻击:
RSA 中的 "知道部分 M 的高位攻击" 是一种攻击 RSA 加密算法的方法之一。该攻击利用了 RSA 加密过程中的一个弱点,即在某些情况下,如果攻击者已经知道了明文 M
的部分高位信息,可以通过对密文 C
进行一些数学运算来推导出完整的明文 M
。
具体来说,假设 RSA 加密的公钥为 (e, n)
,私钥为 (d, n)
。加密过程为 C = M^e mod n
,解密过程为 M = C^d mod n
。
在 "知道部分 M 的高位攻击" 中,攻击者已经知道了明文 M
的一部分高位信息,即 high_m
。攻击者可以构造一个新的明文 M'
,其中 M'
的高位与 high_m
相同,而低位是未知的。然后,攻击者将 M'
加密得到密文 C'
,即 C' = M'^e mod n
。
接下来,攻击者可以通过以下计算推导出完整的明文 M
:
- 计算
M'^e mod n
的平方根X
,即X^2 ≡ M'^e (mod n)
。 - 根据已知的高位信息
high_m
,构造Y = X - high_m
。 - 计算
Y^d mod n
,得到完整的明文M
。
import gmpy2
from Crypto.Util.number import *
n = 131889193322687215946601811511407251196213571687093913054335139712633125177496800529685285401802802683116451016274353008428347997732857844896393358010946452397522017632024075459908859131965234835870443110233375074265933004741459359128684375786221535003839961829770182916778717973782408036072622166388614214899
c = 11188201757361363141578235564807411583085091933389381887827791551369738717117549969067660372214366275040055647621817803877495473068767571465521881010707873686036336475554105314475193676388608812872218943728455841652208711802376453034141883236142677345880594246879967378770573385522326039206400578260353074379
e = 5
flag = b"sm4ll_r00ts_is_brilliant#"
m1 = bytes_to_long(flag)
m1 = m1 << 64
R.<x> = PolynomialRing(Zmod(n))
f = (m1 + x)^e - c
#表示解密方程 (m1 + x)^e - c = 0
f = f.monic()
#多项式 f 调整为首项系数为 1(monic)
root = f.small_roots(X = 2^64)
#2^64是指2的移位次数 通过指定 X = 2^64,它告诉函数只寻找小于等于 2^64 的根
print(root)
m = m1 + root[0]
flag = b"flag{" + long_to_bytes(int(m)) + b"}"
print(flag)
利用sage解密得