保姆级教程:用Python多线程爆破CISCN2018 Java密码题中的‘弱随机数’(附完整代码)

张开发
2026/4/18 4:57:21 15 分钟阅读

分享文章

保姆级教程:用Python多线程爆破CISCN2018 Java密码题中的‘弱随机数’(附完整代码)
从零攻破CISCN2018密码题Python多线程爆破Java弱随机数实战第一次接触CTF密码学题目时看到Java加密算法总有种无从下手的感觉。这道来自CISCN2018的题目完美展示了如何利用编程技巧破解看似复杂的加密系统。本文将带你用Python多线程技术40分钟内爆破出32位随机数密钥最终还原出原始明文。1. 题目分析与关键参数提取拿到题目压缩包后发现只有一个Java源文件。用任意文本编辑器打开可以看到完整的加密算法实现。我们需要重点关注以下几个关键参数static BigInteger p new BigInteger(113607382951770029984953...); // 2048位质数 static BigInteger h new BigInteger(785499889356720883127062...); // 公钥组成部分 String ciphertext a9hgrei...cxqzc; // 密文由两部分组成用分隔密文解析技巧用split()分割字符串得到C1和C2将36进制字符串转为Python的整数类型import base36 # 需要pip安装base36库 c1 base36.loads(a9hgrei...ieco) c2 base36.loads(2q17m8...cxqzc)2. 加密算法数学建模通过分析Java代码我们可以将加密过程抽象为以下数学表达式C1 ≡ 2^r mod p C2 ≡ (h^r mod p) * M mod p其中p和h是已知的公钥参数C1和C2可以从密文中提取r是32位随机整数漏洞所在M是我们要求的明文解密的关键在于找到随机数r。一旦获得r明文可以通过以下公式计算M ≡ C2 / (h^r mod p) mod p3. 多线程爆破方案设计32位整数的取值范围是0到2^32-1约42亿单线程暴力枚举效率太低。我们可以利用多线程将搜索空间分割线程数每个线程负责的范围预计完成时间82^29次方/线程~5小时162^28次方/线程~2.5小时322^27次方/线程~75分钟642^26次方/线程~40分钟提示实际运行时间取决于CPU性能建议在云服务器上执行4. Python多线程实现细节下面是完整的爆破脚本重点讲解几个关键部分from threading import Thread import base36 # 题目参数初始化 p 11360738295177002998495384057893129964980131806509572927886675899422214174408333932150813939357279703161556767193621832795605708456628733877084015367497711 h 7854998893567208831270627233155763658947405610938106998083991389307363085837028364154809577816577515021560985491707606165788274218742692875308216243966916 c1 base36.loads(a9hgrei38ez78hl2kkd6nvookaodyidgti7d9mbvctx3jjniezhlxs1b1xz9m0dzcexwiyhi4nhvazhhj8dwb91e7lbbxa4ieco) def crack_thread(start_r, end_r, thread_id): 单个线程的爆破函数 current start_r while current end_r: if pow(2, current, p) c1: # 找到满足条件的r with open(solution.txt, w) as f: f.write(str(current)) print(f[Thread-{thread_id}] Found r {current}) exit(0) # 每100万次打印进度 if current % 10**6 0: print(f[Thread-{thread_id}] Progress: {current/2**32:.2%}) current 1 # 启动64个线程 thread_count 64 for i in range(thread_count): start i * (2**32 // thread_count) end (i1) * (2**32 // thread_count) if i ! thread_count-1 else 2**32 Thread(targetcrack_thread, args(start, end, i)).start()代码优化点使用Python内置的pow(a,b,c)实现高效的模幂运算比a**b % c快10倍以上每个线程独立检查指定范围发现结果立即保存并终止程序定期打印进度方便监控执行情况5. 结果验证与明文还原当脚本输出找到的r值后例如r152351913用以下代码计算明文r 152351913 # 替换为实际找到的值 c2 base36.loads(2q17m8ajs7509yl9iy39g4znf08bw3b33vibipaa1xt5b8lcmgmk6i5w4830yd3fdqfbqaf82386z5odwssyo3t93y91xqd5jb0zbgvkb00fcmo53sa8eblgw6vahl80ykxeylpr4bpv32p7flvhdtwl4cxqzc) # 计算明文M M (c2 * pow(h, r, p).inverse(p)) % p flag base36.dumps(M) print(Flag:, flag)常见问题解决如果遇到base36模块不存在执行pip install base36模逆元计算使用pow(h,r,p).inverse(p)更可靠最终flag可能需要根据比赛要求添加前缀如ciscn{...}6. 密码学安全启示这道题暴露了加密系统设计中的典型问题弱随机数生成使用Random().nextInt()作为随机源熵不足参数选择不当虽然p是2048位大素数但h的选择可能存在数学弱点缺乏完整性保护无法检测密文是否被篡改在实际开发中应该使用密码学安全的随机数生成器如SecureRandom遵循标准加密协议如RSA-OAEP、ECDSA等对加密结果添加MAC校验7. 性能优化进阶技巧如果要在更短时间内完成爆破可以考虑GPU加速使用CUDA或OpenCL将计算转移到显卡# 示例使用numba库的GPU加速 from numba import cuda cuda.jit def gpu_crack(result, p, c1): tid cuda.grid(1) if tid 2**32: if pow(2, tid, p) c1: result[0] tid分布式计算用Celery或Ray框架分发任务到多台机器算法优化尝试Baby-step Giant-step等空间换时间算法最终在笔者的MacBook Pro (M1 Pro, 10核)上64线程版本仅用28分钟就找到了正确的r值。记住保存好找到的r值下次遇到同类题目可以直接复用。

更多文章