【CTF-CRYPTO-教学-RSA】第七节:低加密指数攻击,已知n和e求c(e很小,m的e次方比n小,c可直接开方得到结果)

背景

e 选得太小(e=3,5,7),且明文 m 也很小(me<n),导致密文 c = me 根本没有"折返"到模 n 的范围内 ,此时 c 就是 me 本身,直接开 e 次方根就能恢复明文!

RSA 加密公式:

c = m e   m o d   n c = m^e \bmod n c=memodn

当 m e < n m^e < n me<n 时,模运算根本没起作用,密文 c 就是 m e m^e me 的精确值。

此时:

m = c e = c 1 / e m = \sqrte{c} = c^{1/e} m=ec =c1/e

这就是低加密指数攻击(Low Encryption Exponent Attack)。

什么是低加密指数攻击?

攻击条件

低加密指数攻击要成立,需要同时满足:

  1. 公钥指数 e 很小(如 e=3)
  2. 明文 m 很小 ,使得 m e < n m^e < n me<n

当 m e < n m^e < n me<n 时,加密公式退化为:

c = m e c = m^e c=me

没有模 n 的"折返",c 就是一个完全的 e 次幂。

为什么不用模 n?

RSA 的安全性来自模 n 的"折返"作用:

  • 模 n 把大数"折叠"到 0 , n − 1 0, n-1 0,n−1 范围内
  • 这个"折叠"使得从 c 反推 m 变得困难(需要分解 n)

但如果 m e < n m^e < n me<n,则:

c = m e   m o d   n = m e ( 因为 m e < n ) c = m^e \bmod n = m^e \quad (\text{因为 } m^e < n) c=memodn=me(因为 me<n)

此时 c 没有被"折叠",直接开方即可。

什么时候会出现 m e < n m^e < n me<n?

这取决于 e 和 n 的大小关系:

  • e=3 :只要 m < n 3 m < \sqrt3{n} m<3n ,就有 m 3 < n m^3 < n m3<n
  • e=5 :只要 m < n 5 m < \sqrt5{n} m<5n ,就有 m 5 < n m^5 < n m5<n

而 n 通常是几百位的十进制数,所以:

  • 对于 e=3,只要明文 m 小于 n 3 \sqrt3{n} 3n (大约是 n 的 1/3 位数十进制),攻击就成立
  • 如果明文是短字符串(如 flag{...}),往往满足条件

简单例子

我们用 p=3, q=11 来演示,数字小到可以在草稿纸上算完。

生成密钥

  • n = p × q = 3 × 11 = 33
  • φ(n) = (p-1)(q-1) = 2 × 10 = 20
  • 选 e = 3(gcd(3, 20) = 1 ✓),公钥 (e, n) = (3, 33)

加密小明文

场景一:明文很小,m^e < n

要加密明文 m = 2:

  • c = m^e mod n = 2^3 mod 33 = 8
  • 检查:2^3 = 8 < 33 ✓ 没有"折返"!
  • 所以 c = 8 就是 2^3 的精确值

攻击:直接开方

  • m = √3{c} = √3{8} = 2 ✓ 恢复明文!

场景二:明文稍大,m^e > n

要加密明文 m = 4:

  • c = m^e mod n = 4^3 mod 33
  • 4^3 = 64 > 33,发生"折返"
  • 64 mod 33 = 64 - 33 = 31
  • 所以 c = 31

攻击:直接开方失败

  • √3{31} ≈ 3.14,不是整数
  • 因为 31 是 64 mod 33 的结果,不是完全立方数
  • 此时需要用其他方法(如小 n 分解)

代码实现

python 复制代码
# ============================================================
# RSA 低加密指数攻击(手算例子)
# ============================================================
#
# 场景: n=33, e=3
#      m=2 时: c=8,  m^3 < n,  直接开方 m=∛8=2 ✓
#      m=4 时: c=31, m^3 > n,  开方失败,需要分解 n
# ============================================================


def integer_nth_root(x, n):
    """
    计算 x 的 n 次整数根(精确)
    返回整数 r 使得 r^n <= x < (r+1)^n
    如果 x 不是完全 n 次幂,返回 None
    """
    if x < 0:
        return None
    if x == 0:
        return 0
    # 二分查找
    low, high = 1, x
    while low <= high:
        mid = (low + high) // 2
        mid_n = mid ** n
        if mid_n == x:
            return mid
        elif mid_n < x:
            low = mid + 1
        else:
            high = mid - 1
    return None  # 不是完全 n 次幂


def main():
    # ---- 公钥 ----
    n = 33
    e = 3

    print("=== RSA 低加密指数攻击 ===")
    print(f"公钥 (e, n) = ({e}, {n})")
    print(f"注意: e = {e} 很小,可能存在低加密指数攻击")
    print()

    # ============ 场景一:m^e < n ============
    print("=== 场景一:m=2, m^3 < n ===")
    m1 = 2
    c1 = pow(m1, e, n)
    print(f"明文 m = {m1}")
    print(f"密文 c = m^e mod n = {m1}^{e} mod {n} = {c1}")
    print(f"检查: m^e = {m1}^{e} = {m1**e} < {n}? {m1**e < n}")

    # 攻击:直接开方
    m1_recovered = integer_nth_root(c1, e)
    if m1_recovered is not None:
        print(f"攻击: m = ∛c = ∛{c1} = {m1_recovered} ✓ 成功!")
    else:
        print(f"攻击: ∛{c1} 不是整数,攻击失败")
    print()

    # ============ 场景二:m^e > n ============
    print("=== 场景二:m=4, m^3 > n ===")
    m2 = 4
    c2 = pow(m2, e, n)
    print(f"明文 m = {m2}")
    print(f"密文 c = m^e mod n = {m2}^{e} mod {n} = {c2}")
    print(f"检查: m^e = {m2}^{e} = {m2**e} < {n}? {m2**e < n}")

    # 攻击:直接开方
    m2_recovered = integer_nth_root(c2, e)
    if m2_recovered is not None:
        print(f"攻击: m = ∛c = ∛{c2} = {m2_recovered} ✓ 成功!")
    else:
        print(f"攻击: ∛{c2} ≈ {c2**(1/3):.2f},不是整数,攻击失败")
        print(f"      因为 m^e = {m2**e} > {n},发生了模 n 折返")
    print()

    # ============ 总结 ============
    print("=== 总结 ===")
    print("低加密指数攻击成功的条件:")
    print(f"  1. e 很小(如 e={e})")
    print(f"  2. 明文 m 很小,使得 m^e < n")
    print(f"  3. 密文 c = m^e(没有发生模 n 折返)")
    print()
    print("当满足条件时,c 就是完全 e 次幂,直接开方即可恢复 m。")


if __name__ == "__main__":
    main()

运行结果:

bash 复制代码
=== RSA 低加密指数攻击 ===
公钥 (e, n) = (3, 33)
注意: e = 3 很小,可能存在低加密指数攻击

=== 场景一:m=2, m^3 < n ===
明文 m = 2
密文 c = m^e mod n = 2^3 mod 33 = 8
检查: m^e = 2^3 = 8 < 33? True
攻击: m = ∛c = ∛8 = 2 ✓ 成功!

=== 场景二:m=4, m^3 > n ===
明文 m = 4
密文 c = m^e mod n = 4^3 mod 33 = 31
检查: m^e = 4^3 = 64 < 33? False
攻击: ∛31 ≈ 3.14,不是整数,攻击失败
      因为 m^e = 64 > 33,发生了模 n 折返

=== 总结 ===
低加密指数攻击成功的条件:
  1. e 很小(如 e=3)
  2. 明文 m 很小,使得 m^e < n
  3. 密文 c = m^e(没有发生模 n 折返)

当满足条件时,c 就是完全 e 次幂,直接开方即可恢复 m。

扩展:当 m 稍大时怎么办?

如果 m e m^e me 稍大于 n n n,即 m e = c + k ⋅ n m^e = c + k \cdot n me=c+k⋅n(k 很小),可以:

  1. 枚举 k = 0, 1, 2, ...
  2. 计算 m e = c + k ⋅ n m^e = c + k \cdot n me=c+k⋅n
  3. 检查 m e m^e me 是否为完全 e 次幂
  4. 如果是,则 m = c + k ⋅ n e m = \sqrte{c + k \cdot n} m=ec+k⋅n

这就是 Coppersmith 低加密指数攻击 的简化版。

公式:

m = c + k ⋅ n e m = \sqrte{c + k \cdot n} m=ec+k⋅n

其中 k 从 0 开始枚举,直到找到整数解。

总结

低加密指数攻击的关键:

  1. 识别条件:e 很小(如 e=3),且明文 m 很小
  2. 检查方法:尝试对密文 c 直接开 e 次方根
  3. 扩展方法:如果直接开方失败,枚举 k,用 Coppersmith 方法求解

在实际 CTF 比赛中,看到 e=3 或 e=5 这样的小指数,第一时间就应该想到低加密指数攻击!

作业1:低加密指数攻击(e=3)

题目

https://ctf2.dasctf.com/dashboard/practice/b9bbb32f-f186-458f-b90b-12440c0f6aea?tab=challenges&challenge=4b20fd31-ac8a-4b96-960c-5ad74ead3ec4

复制代码
n = 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793
e = 0x3
c = 0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365

求明文作为 flag 提交。

解题过程

第一步:分析已知条件
  • 已知 n(十六进制),e=3,c(十六进制)
  • e=3 很小,怀疑是低加密指数攻击
  • 需要检查 c 是否为完全立方数
第二步:将十六进制转为十进制
python 复制代码
n = 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793
e = 3
c = 0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365
第三步:尝试直接开立方

检查 c 是否为完全立方数:

python 复制代码
m = integer_nth_root(c, 3)

如果是整数,则攻击成功!

第四步:如果不是完全立方数

如果直接开方失败,说明 m e ≥ n m^e \ge n me≥n,尝试 Coppersmith 方法:

python 复制代码
for k in range(0, 100):  # 枚举 k
    m_e = c + k * n
    m = integer_nth_root(m_e, 3)
    if m is not None:
        print(f"找到 k={k}, m={m}")
        break
第五步:将明文整数转为字节串
python 复制代码
m_bytes = m.to_bytes((m.bit_length() + 7) // 8, 'big')
print(m_bytes.decode('utf-8'))

具体实现代码

python 复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
低加密指数攻击
使用精确的整数开方方法
"""

def integer_nth_root(x, n):
    """
    计算 x 的 n 次整数根(精确,使用二分查找)
    返回整数 r 使得 r^n == x
    如果 x 不是完全 n 次幂,返回 None
    """
    if x < 0:
        return None
    if x == 0:
        return 0
    if x == 1:
        return 1

    # 二分查找
    low = 1
    # 估算上界:x 的位数除以 n
    # 对于立方根,上界约为 2^(bits/3)
    high = 1 << ((x.bit_length() // n) + 2)

    while low <= high:
        mid = (low + high) // 2
        mid_n = mid ** n

        if mid_n == x:
            return mid
        elif mid_n < x:
            low = mid + 1
        else:
            high = mid - 1

    return None


def main():
    # ---- 题目参数(十六进制)----
    n_hex = "52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793"
    e = 3
    c_hex = "10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365"

    # 转为十进制
    n = int(n_hex, 16)
    c = int(c_hex, 16)

    print("===低加密指数攻击(e=3)===")
    print(f"e = {e}")
    print(f"n(位数)= {n.bit_length()} bits")
    print(f"c(位数)= {c.bit_length()} bits")
    print()

    # ---- 方法一:直接开立方 ----
    print("=== 方法一:直接开立方 ===")
    print("假设 m^3 < n,即密文 c 没有发生模 n 折返")

    # 检查 c < n
    print(f"检查: c < n? {c < n}")
    if c < n:
        print("  c < n,说明可能 m^3 < n,可以尝试直接开立方")
    else:
        print("  c >= n,说明 m^3 > n,需要使用 Coppersmith 方法")
    print()

    # 尝试开立方(使用精确的二分查找)
    print("尝试 m = ∛c (使用二分查找精确计算)...")
    m = integer_nth_root(c, 3)

    if m is not None:
        print(f"✓ c 是完全立方数!")
        print(f"m = ∛c = {m}")

        # 验证
        print(f"\n验证:")
        m_cubed = m ** 3
        print(f"  m^3 = {m_cubed}")
        print(f"  c   = {c}")
        print(f"  m^3 == c? {m_cubed == c}")

        if m_cubed == c:
            # 转为字节串
            print(f"\n将明文整数转为字节串:")
            m_bytes = m.to_bytes((m.bit_length() + 7) // 8, 'big')
            print(f"明文(字节串): {m_bytes}")
            try:
                decoded = m_bytes.decode('utf-8')
                print(f"明文(字符串): {decoded}")
                print(f"\n✓ 找到 flag: {decoded}")
            except UnicodeDecodeError:
                print(f"明文(hex): {m_bytes.hex()}")
        else:
            print("✗ 验证失败,m^3 != c")
    else:
        print(f"✗ c 不是完全立方数")
        print()

        # ---- 方法二:Coppersmith 方法(枚举 k)----
        print("=== 方法二:Coppersmith 方法(枚举 k)===")
        print("假设 m^3 = c + k*n,枚举 k 求解")
        print()

        found = False
        max_k = 100  # 最多枚举 100 次

        print(f"开始枚举 k 从 0 到 {max_k-1}...")
        for k in range(0, max_k):
            m_e = c + k * n
            m = integer_nth_root(m_e, 3)

            if m is not None:
                print(f"\n✓ 找到解!k = {k}")
                print(f"m = ∛(c + k*n) = {m}")

                # 验证
                print(f"\n验证:")
                m_cubed = m ** 3
                print(f"  m^3 == c + k*n? {m_cubed == m_e}")

                if m_cubed == m_e:
                    # 转为字节串
                    print(f"\n将明文整数转为字节串:")
                    m_bytes = m.to_bytes((m.bit_length() + 7) // 8, 'big')
                    print(f"明文(字节串): {m_bytes}")
                    try:
                        decoded = m_bytes.decode('utf-8')
                        print(f"明文(字符串): {decoded}")
                        print(f"\n✓ 找到 flag: {decoded}")
                    except UnicodeDecodeError:
                        print(f"明文(hex): {m_bytes.hex()}")
                    found = True
                    break
                else:
                    print("  验证失败,继续枚举...")

        if not found:
            print(f"\n✗ 枚举 k=0..{max_k-1} 均未找到解")
            print("  可能需要更大的 k 或其他方法")


if __name__ == "__main__":
    main()

运行结果

bash 复制代码
=== 低加密指数攻击(e=3)===
e = 3
n(位数)= 2047 bits
c(位数)= 909 bits

=== 方法一:直接开立方 ===
假设 m^3 < n,即密文 c 没有发生模 n 折返
检查: c < n? True
  c < n,说明可能 m^3 < n,可以尝试直接开立方

尝试 m = ∛c (使用二分查找精确计算)...
✓ c 是完全立方数!
m = ∛c = 13040004482819713819817340524563023159919305047824600478799740488797710355579494486728991357

验证:
  m^3 = 2217344750798296091193230394221582894657909643174934416842588335871298152598368701484028832407289746218387783855373449002121088413603751014125921242419602155087438902181522441026460003722677539409576093794862185483713606547386172606576925933695952279401957552813065318376293
  c   = 2217344750798296091193230394221582894657909643174934416842588335871298152598368701484028832407289746218387783855373449002121088413603751014125921242419602155087438902181522441026460003722677539409576093794862185483713606547386172606576925933695952279401957552813065318376293
  m^3 == c? True

将明文整数转为字节串:
明文(字节串): b'flag{25df8caf006ee5db94d48144c33b2c3b}'
明文(字符串): flag{25df8caf006ee5db94d48144c33b2c3b}

✓ 找到 flag: flag{25df8caf006ee5db94d48144c33b2c3b}

答案

复制代码
flag{25df8caf006ee5db94d48144c33b2c3b}

作业2:与作业1方式相同

题目

https://ctf2.dasctf.com/dashboard/practice/b9bbb32f-f186-458f-b90b-12440c0f6aea?tab=challenges&challenge=62264ff9-d067-4c55-872d-89452373c9c5

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

flag = '*********************'
hex_flag=int(flag.encode("hex"),16)

p=getPrime(512)
q=getPrime(512)

n=p*q
e=0x3
c=pow(hex_flag,e,n)

print("n=",hex(n))
print("e=",hex(e))
print("c=",hex(c))

'''
('n=', '0x86f4be77b79e166a6311e7982ba2e5ff479db93a01c56034479a9e35382293c35769da222974e9425829099aa4fe4f41185283866202042b356194bab312e6ed2fb0b10b1b74767dc1cc5306872d33b1f3b75612c594751ec70e4cf5fccc6fceafe0401648869cc40425a176ab70286d92a29dfd675f2384c9383e0a9750b25bL')
('e=', '0x3')
('c=', '0x10652cdf7ed2bc53f58b321f476c3a3cf3281e541f4d533a73a0fcbf525230f2e01c183dee660676317ea99250202548e5525b0c14adbeb77d4fa7e2e1d339L')
'''

解题过程

python 复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
低加密指数攻击(e=3)
使用精确的整数开方方法
"""

def integer_nth_root(x, n):
    """
    计算 x 的 n 次整数根(精确,使用二分查找)
    返回整数 r 使得 r^n == x
    如果 x 不是完全 n 次幂,返回 None
    """
    if x < 0:
        return None
    if x == 0:
        return 0
    if x == 1:
        return 1

    # 二分查找
    low = 1
    # 估算上界:x 的位数除以 n
    # 对于立方根,上界约为 2^(bits/3)
    high = 1 << ((x.bit_length() // n) + 2)

    while low <= high:
        mid = (low + high) // 2
        mid_n = mid ** n

        if mid_n == x:
            return mid
        elif mid_n < x:
            low = mid + 1
        else:
            high = mid - 1

    return None


def main():
    # ---- 题目参数(十六进制)----
    n_hex = "86f4be77b79e166a6311e7982ba2e5ff479db93a01c56034479a9e35382293c35769da222974e9425829099aa4fe4f41185283866202042b356194bab312e6ed2fb0b10b1b74767dc1cc5306872d33b1f3b75612c594751ec70e4cf5fccc6fceafe0401648869cc40425a176ab70286d92a29dfd675f2384c9383e0a9750b25b"
    e = 3
    c_hex = "10652cdf7ed2bc53f58b321f476c3a3cf3281e541f4d533a73a0fcbf525230f2e01c183dee660676317ea99250202548e5525b0c14adbeb77d4fa7e2e1d339"

    # 转为十进制
    n = int(n_hex, 16)
    c = int(c_hex, 16)

    print("=== 低加密指数攻击(e=3)===")
    print(f"e = {e}")
    print(f"n(位数)= {n.bit_length()} bits")
    print(f"c(位数)= {c.bit_length()} bits")
    print()

    # ---- 方法一:直接开立方 ----
    print("=== 方法一:直接开立方 ===")
    print("假设 m^3 < n,即密文 c 没有发生模 n 折返")

    # 检查 c < n
    print(f"检查: c < n? {c < n}")
    if c < n:
        print("  c < n,说明可能 m^3 < n,可以尝试直接开立方")
    else:
        print("  c >= n,说明 m^3 > n,需要使用 Coppersmith 方法")
    print()

    # 尝试开立方(使用精确的二分查找)
    print("尝试 m = ∛c (使用二分查找精确计算)...")
    m = integer_nth_root(c, 3)

    if m is not None:
        print(f"✓ c 是完全立方数!")
        print(f"m = ∛c = {m}")

        # 验证
        print(f"\n验证:")
        m_cubed = m ** 3
        print(f"  m^3 = {m_cubed}")
        print(f"  c   = {c}")
        print(f"  m^3 == c? {m_cubed == c}")

        if m_cubed == c:
            # 转为字节串
            print(f"\n将明文整数转为字节串:")
            m_bytes = m.to_bytes((m.bit_length() + 7) // 8, 'big')
            print(f"明文(字节串): {m_bytes}")
            try:
                decoded = m_bytes.decode('utf-8')
                print(f"明文(字符串): {decoded}")
                print(f"\n✓ 找到 flag: {decoded}")
            except UnicodeDecodeError:
                print(f"明文(hex): {m_bytes.hex()}")
        else:
            print("✗ 验证失败,m^3 != c")
    else:
        print(f"✗ c 不是完全立方数")
        print()

        # ---- 方法二:Coppersmith 方法(枚举 k)----
        print("=== 方法二:Coppersmith 方法(枚举 k)===")
        print("假设 m^3 = c + k*n,枚举 k 求解")
        print()

        found = False
        max_k = 100  # 最多枚举 100 次

        print(f"开始枚举 k 从 0 到 {max_k-1}...")
        for k in range(0, max_k):
            m_e = c + k * n
            m = integer_nth_root(m_e, 3)

            if m is not None:
                print(f"\n✓ 找到解!k = {k}")
                print(f"m = ∛(c + k*n) = {m}")

                # 验证
                print(f"\n验证:")
                m_cubed = m ** 3
                print(f"  m^3 == c + k*n? {m_cubed == m_e}")

                if m_cubed == m_e:
                    # 转为字节串
                    print(f"\n将明文整数转为字节串:")
                    m_bytes = m.to_bytes((m.bit_length() + 7) // 8, 'big')
                    print(f"明文(字节串): {m_bytes}")
                    try:
                        decoded = m_bytes.decode('utf-8')
                        print(f"明文(字符串): {decoded}")
                        print(f"\n✓ 找到 flag: {decoded}")
                    except UnicodeDecodeError:
                        print(f"明文(hex): {m_bytes.hex()}")
                    found = True
                    break
                else:
                    print("  验证失败,继续枚举...")

        if not found:
            print(f"\n✗ 枚举 k=0..{max_k-1} 均未找到解")
            print("  可能需要更大的 k 或其他方法")


if __name__ == "__main__":
    main()

运行结果

bash 复制代码
=== 低加密指数攻击(e=3)===
e = 3
n(位数)= 1024 bits
c(位数)= 501 bits

=== 方法一:直接开立方 ===
假设 m^3 < n,即密文 c 没有发生模 n 折返
检查: c < n? True
  c < n,说明可能 m^3 < n,可以尝试直接开立方

尝试 m = ∛c (使用二分查找精确计算)...
✓ c 是完全立方数!
m = ∛c = 149691910166879983220013334339944014369691538367017

验证:
  m^3 = 3354246620726085986568668128373090812593945499332956611216503173394622300212425527028396698978553852269462669721310427515531023131901147683787903193913
  c   = 3354246620726085986568668128373090812593945499332956611216503173394622300212425527028396698978553852269462669721310427515531023131901147683787903193913
  m^3 == c? True

将明文整数转为字节串:
明文(字节串): b'flag is md5("SmallM")'
明文(字符串): flag is md5("SmallM")

✓ 找到 flag: flag is md5("SmallM")
相关推荐
hengdonghui3 天前
Writeup 4 N1BOOK afr_1
ctf·伪协议·任意文件读取
hengdonghui3 天前
Writeup 4 N1BOOK 常见的搜集
ctf·信息搜集
hengdonghui4 天前
Writeup 4 N1BOOK SQL注入-1
ctf·sql注入·union·字符型注入
hengdonghui5 天前
Writeup 4 红帽杯 2021 WebsiteManger
web·ctf·ssrf·sql布尔盲注
hengdonghui7 天前
Writeup 4 2020 - 之江杯 - 异常的流量分析
wireshark·ctf·流量分析
hengdonghui7 天前
Writeup 4 津门杯 2021 Web hate_php
php·web·ctf·通配符
hengdonghui7 天前
Writeup 4 红帽杯 2021 Web Find_It
web·ctf·备份文件泄露
hengdonghui8 天前
Writeup 4 强网杯 2019 强网先锋打野
ctf·misc·zsteg
hengdonghui8 天前
Writeup 4 NUAA 2017 robots
android·ctf·re