密码挑战 - ^o^ writeup by AI

密码挑战 - ^o^ writeup by AI

题目描述

这是一道密码学挑战题,给出了以下加密代码和输出参数:

python 复制代码
from Crypto.Util.number import *
from secret import n,o,_,flag

def any(m):
    return bytes_to_long(m)^o^pow(2,2**_,n)

print(n,o,_,any(flag))

已知参数

  • n = 126176329335043454027341235009057683290541781096785538088437185779950106283534462102786883
  • o = 22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165185658681843519312254372108072512792854040590016772780908271525769845284796145687079308339
  • _ = 1138895128842708275167
  • encrypted_flag = 22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165145471041075065947806083270394708336810934202426175949363009508477208686445248781032485832

考点分析

  1. 异或运算的性质A ^ B ^ C = DA = D ^ B ^ C
  2. 欧拉定理 :当 gcd(a, n) = 1 时,a^φ(n) ≡ 1 (mod n)
  3. 大整数因子分解:使用 Pollard's rho 算法
  4. 模幂运算优化:利用欧拉函数简化超大指数计算

解题思路

1. 分析加密公式

加密函数:

python 复制代码
def any(m):
    return bytes_to_long(m) ^ o ^ pow(2, 2**_, n)

解密公式(利用异或性质):

python 复制代码
bytes_to_long(flag) = encrypted_flag ^ o ^ pow(2, 2**_, n)

2. 关键难点

直接计算 pow(2, 2**_, n) 是不可能的,因为:

  • _ = 1138895128842708275167(70 位)
  • 2**_ 是一个天文数字(2 的 10^21 次方)
  • 无法直接存储或计算这么大的指数

3. 使用欧拉定理优化

根据欧拉定理:

  • gcd(a, n) = 1,则 a^φ(n) ≡ 1 (mod n)
  • 因此 a^b mod n = a^(b mod φ(n)) mod n

所以:pow(2, 2**_, n) = pow(2, 2**_ mod φ(n), n)

现在问题转化为:

  1. 分解 n,计算 φ(n)
  2. 计算 2**_ mod φ(n)
  3. 计算 pow(2, 结果,n)

4. 分解 n

n 是 296 位的大整数,使用 Pollard's rho 算法成功分解为 10 个素因子:

复制代码
n = 806952673 × 648863389 × 973139887 × 914351299 × 611738359 
    × 834612803 × 856368371 × 940957051 × 775357619 × 848994661

5. 计算 φ(n)

对于多素因子的情况:

复制代码
φ(n) = n × ∏(1 - 1/p) = n × (p1-1)/p1 × (p2-1)/p2 × ... × (pk-1)/pk

6. 逐步计算

python 复制代码
# 步骤 1: 计算 2**_ mod φ(n)
exp_mod = pow(2, _, phi)

# 步骤 2: 计算 pow(2, exp_mod, n)
power_result = pow(2, exp_mod, n)

# 步骤 3: 解密 flag
flag_long = encrypted_flag ^ o ^ power_result
flag = long_to_bytes(flag_long)

详细步骤

步骤 1: 实现 Pollard's rho 算法分解 n

python 复制代码
def pollard_rho(n):
    if n % 2 == 0:
        return 2
    
    x = 2
    y = 2
    d = 1
    c = 1
    
    def f(x):
        return (x * x + c) % n
    
    while d == 1:
        x = f(x)
        y = f(f(y))
        d = math.gcd(abs(x - y), n)
        
        if d != 1 and d != n:
            return d
        
        if x == y:
            c += 1
            x = 2
            y = 2
            d = 1
    
    return d

步骤 2: 递归分解获取所有素因子

python 复制代码
def factorize(n):
    if n == 1:
        return []
    
    if isPrime(n):
        return [n]
    
    # 试除法检查小素数
    small_primes = [2, 3, 5, 7, 11, ...]
    for p in small_primes:
        if n % p == 0:
            return [p] + factorize(n // p)
    
    # 使用 Pollard's rho
    factor = pollard_rho(n)
    return factorize(factor) + factorize(n // factor)

步骤 3: 计算 φ(n)

python 复制代码
factors = factorize(n)  # 得到 10 个素因子
phi = n
unique_factors = set(factors)
for p in unique_factors:
    phi = phi // p * (p - 1)

步骤 4: 使用欧拉定理简化指数

python 复制代码
# 计算 2**_ mod φ(n)
exp_mod = pow(2, _, phi)

# 计算 pow(2, exp_mod, n)
power_result = pow(2, exp_mod, n)

步骤 5: 解密 flag

python 复制代码
flag_long = encrypted_flag ^ o ^ power_result
flag = long_to_bytes(flag_long)

完整代码

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

def pollard_rho(n):
    """Pollard's rho 算法分解大整数"""
    if n % 2 == 0:
        return 2
    
    x = 2
    y = 2
    d = 1
    c = 1
    
    def f(x):
        return (x * x + c) % n
    
    while d == 1:
        x = f(x)
        y = f(f(y))
        d = math.gcd(abs(x - y), n)
        
        if d != 1 and d != n:
            return d
        
        # 如果失败,改变参数重试
        if x == y:
            c += 1
            x = 2
            y = 2
            d = 1
    
    return d

def factorize(n):
    """递归分解 n"""
    if n == 1:
        return []
    
    if isPrime(n):
        return [n]
    
    # 试除法检查小素数
    small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
    for p in small_primes:
        if n % p == 0:
            return [p] + factorize(n // p)
    
    # 使用 Pollard's rho
    factor = pollard_rho(n)
    if factor == n:
        print(f"无法分解:{n}")
        return [n]
    
    return factorize(factor) + factorize(n // factor)

def solve():
    # 已知参数
    n = 126176329335043454027341235009057683290541781096785538088437185779950106283534462102786883
    o = 22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165185658681843519312254372108072512792854040590016772780908271525769845284796145687079308339
    _ = 1138895128842708275167
    encrypted_flag = 22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165145471041075065947806083270394708336810934202426175949363009508477208686445248781032485832
    
    print("=== 分解 n ===")
    factors = factorize(n)
    print(f"因子:{factors}")
    
    if len(factors) == 2:
        p, q = sorted(factors, reverse=True)
        print(f"\np = {p}")
        print(f"q = {q}")
        
        # 计算 φ(n)
        phi = (p - 1) * (q - 1)
        print(f"\nφ(n) = {phi}")
        
        # 计算 2**_ mod φ(n)
        print(f"\n=== 计算指数 ===")
        exp_mod = pow(2, _, phi)
        print(f"2**_ mod φ(n) = {exp_mod}")
        
        # 计算 pow(2, 2**_, n)
        print(f"\n=== 计算幂 ===")
        power_result = pow(2, exp_mod, n)
        print(f"pow(2, 2**_, n) = {power_result}")
        
        # 解密
        print(f"\n=== 解密 ===")
        flag_long = encrypted_flag ^ o ^ power_result
        print(f"flag_long = {flag_long}")
        
        # 转换为字节
        flag_bytes = long_to_bytes(flag_long)
        print(f"flag = {flag_bytes}")
        
        # 尝试打印为字符串
        try:
            flag_str = flag_bytes.decode('utf-8')
            print(f"flag (文本) = {flag_str}")
        except:
            print("无法解码为 UTF-8")
            
        # 检查是否包含可打印字符
        printable = all(32 <= b < 127 or b in [10, 13, 9] for b in flag_bytes)
        print(f"是否全为可打印字符:{printable}")
    else:
        print(f"因子数量不是 2,无法继续:{len(factors)}")

if __name__ == "__main__":
    solve()

总结

这道题的核心在于:

  1. 识别异或运算的可逆性:加密过程全是异或操作,解密只需再次异或相同值
  2. 处理超大指数2**(10^21) 无法直接计算,必须使用数学优化
  3. 欧拉定理的应用a^b mod n = a^(b mod φ(n)) mod n
  4. 大整数分解:296 位的 n 虽然很大,但它是多个小素数的乘积,可以用 Pollard's rho 算法快速分解
  5. 多素因子的φ(n) 计算:当 n 有多个不同素因子时,需要正确应用公式

关键公式回顾:

  • 加密:ciphertext = flag_long ^ o ^ pow(2, 2**_, n)
  • 解密:flag_long = ciphertext ^ o ^ pow(2, 2**_, n)
  • 欧拉定理:pow(2, 2**_, n) = pow(2, pow(2, _, φ(n)) % φ(n), n)

提问

请阅读代码,解出这道CTF题目。

相关推荐
爱钓鱼的程序员小郭4 小时前
阿里云自动配置安全组IP白名单
python·tcp/ip·安全·阿里云
中科固源4 小时前
强制性国标在路上:预解读《民用无人驾驶航空器数据链路网络安全要求》(一)
安全·网络安全·模糊测试·低空经济·商业航天
暮色千里.5324 小时前
多因素认证中的漏洞
网络·安全·web安全
珠海西格4 小时前
1MW光伏项目“四可”装置数据采集类设备具体配置详解
服务器·网络·人工智能·分布式·安全
小二·4 小时前
企业级网络安全深度解析:从协议层到云原生的攻防实战与架构设计
安全·web安全·云原生
wanhengidc4 小时前
企业如何有效利用高防服务器
运维·服务器·网络·安全·web安全·智能手机
小手智联老徐4 小时前
在 macOS 上使用 Lima 虚拟机安全部署 OpenClaw:构建你的 AI 隔离沙箱
人工智能·安全·macos·ai智能体·openclaw
code_pgf5 小时前
Jetson Orin NX 16G部署openclaw及本地化安全配置及建议
人工智能·安全·ai
竹下为生5 小时前
大模型安全与语义平滑防御
安全