news 2026/4/18 18:43:24

保姆级教程:用Python复现CISCN2018 Java密码题,手把手教你写base36转换与多线程爆破脚本

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
保姆级教程:用Python复现CISCN2018 Java密码题,手把手教你写base36转换与多线程爆破脚本

从零破解CISCN2018 Java密码题:Python实现Base36与多线程爆破实战

在CTF竞赛中,遇到Java编写的密码学题目往往让初学者感到棘手。今天我们就以CISCN2018的crackme-java为例,手把手教你如何用Python还原整个破解流程。不同于直接使用现成工具,我们将从底层原理出发,一步步构建自己的解题工具链。

1. 理解题目加密机制

首先需要完整分析Java源代码的加密逻辑。题目提供了一个Test1类,核心是pkEnc加密方法:

public static String pkEnc(String val) { BigInteger[] ret = new BigInteger[2]; BigInteger bVal = new BigInteger(val.toLowerCase(), 36); BigInteger r = new BigInteger(new Random().nextInt() + ""); ret[0] = two.modPow(r, p); ret[1] = h.modPow(r, p).multiply(bVal); return ret[0].toString(36) + "==" + ret[1].toString(36); }

加密过程可以分解为以下几个数学步骤:

  1. 将明文val转换为Base36编码的大整数bVal
  2. 生成一个随机整数r(32位有符号整数范围)
  3. 计算C1 = 2^r mod p
  4. 计算C2 = h^r mod p * bVal
  5. 返回C1和C2的Base36字符串,用"=="连接

关键参数说明

  • p:一个256位的大质数
  • h:与p关联的公钥参数
  • two:常数2的BigInteger表示

2. Base36编码的Python实现

Java的BigInteger构造函数支持直接解析Base36字符串,而Python需要一些额外处理。Python内置的int()函数虽然支持Base36转换,但我们需要完整实现编码和解码:

import string BASE36_CHARS = string.digits + string.ascii_lowercase def base36_encode(number): if not isinstance(number, int): raise TypeError("Number must be integer") if number < 0: return '-' + base36_encode(-number) if number == 0: return '0' result = [] while number > 0: number, remainder = divmod(number, 36) result.append(BASE36_CHARS[remainder]) return ''.join(reversed(result)) def base36_decode(s): if s.startswith('-'): return -base36_decode(s[1:]) return int(s, 36)

性能对比

方法编码速度(ops/s)解码速度(ops/s)内存使用
Python内置int()1,200,000950,000
自定义实现850,000700,000中等
Java BigInteger1,500,0001,100,000

提示:实际CTF解题中建议直接使用Python内置int()函数,自定义实现主要用于理解原理

3. 多线程爆破攻击设计

加密算法的弱点在于r的取值范围有限(32位整数)。我们可以通过暴力枚举找到正确的r值。为了提高效率,需要使用多线程技术。

3.1 线程分配策略

将32位整数空间均匀分配给多个线程。假设使用16个线程:

from threading import Thread import math def crack_thread(start_r, end_r, p, c1, result): current = start_r while current <= end_r: if pow(2, current, p) == c1: result['r'] = current return current += 1 def parallel_crack(p, c1, thread_count=16): max_r = 2**31 - 1 # 32位有符号整数最大值 chunk_size = max_r // thread_count result = {} threads = [] for i in range(thread_count): start = i * chunk_size end = start + chunk_size - 1 if i < thread_count - 1 else max_r t = Thread(target=crack_thread, args=(start, end, p, c1, result)) threads.append(t) t.start() for t in threads: t.join() return result.get('r')

3.2 进度监控与优化

长时间运行的爆破需要进度反馈。我们可以添加进度报告机制:

def crack_thread_with_progress(start_r, end_r, p, c1, result, thread_id): current = start_r report_interval = (end_r - start_r) // 10 # 10%进度报告 while current <= end_r: if current % report_interval == 0: print(f"Thread {thread_id}: {100*(current-start_r)/(end_r-start_r):.1f}%") if pow(2, current, p) == c1: result['r'] = current return current += 1

线程数选择建议

CPU核心数推荐线程数预计完成时间
4核8-12线程约60分钟
8核16-24线程约30分钟
16核32线程约15分钟

4. 完整解题流程实现

现在我们将所有步骤整合成一个完整的解题脚本:

import math from threading import Thread from concurrent.futures import ThreadPoolExecutor # 题目给定参数 p = 11360738295177002998495384057893129964980131806509572927886675899422214174408333932150813939357279703161556767193621832795605708456628733877084015367497711 h = 7854998893567208831270627233155763658947405610938106998083991389307363085837028364154809577816577515021560985491707606165788274218742692875308216243966916 ciphertext = "a9hgrei38ez78hl2kkd6nvookaodyidgti7d9mbvctx3jjniezhlxs1b1xz9m0dzcexwiyhi4nhvazhhj8dwb91e7lbbxa4ieco==2q17m8ajs7509yl9iy39g4znf08bw3b33vibipaa1xt5b8lcmgmk6i5w4830yd3fdqfbqaf82386z5odwssyo3t93y91xqd5jb0zbgvkb00fcmo53sa8eblgw6vahl80ykxeylpr4bpv32p7flvhdtwl4cxqzc" def decode_ciphertext(cipher): c1_str, c2_str = cipher.split("==") return int(c1_str, 36), int(c2_str, 36) def find_r(p, c1, max_threads=16): max_r = 2**31 - 1 chunk_size = max_r // max_threads result = {} def worker(start, end): current = start while current <= end: if pow(2, current, p) == c1: result['r'] = current return current += 1 with ThreadPoolExecutor(max_workers=max_threads) as executor: futures = [] for i in range(max_threads): start = i * chunk_size end = start + chunk_size - 1 if i < max_threads - 1 else max_r futures.append(executor.submit(worker, start, end)) for future in futures: future.result() if 'r' in result: executor.shutdown(wait=False) for f in futures: f.cancel() break return result.get('r') def decrypt(c2, h, r, p): hr_p = pow(h, r, p) m = (c2 * pow(hr_p, -1, p)) % p return m def main(): c1, c2 = decode_ciphertext(ciphertext) print("Starting r brute force...") r = find_r(p, c1) if r is None: print("Failed to find r") return print(f"Found r: {r}") plain_num = decrypt(c2, h, r, p) plaintext = base36_encode(plain_num) print(f"Decrypted plaintext: {plaintext}") if __name__ == "__main__": main()

执行流程说明

  1. 解析密文为C1和C2两个大整数
  2. 使用多线程暴力搜索找到正确的r值
  3. 利用r值解密得到明文数字
  4. 将明文数字转换为Base36字符串

5. 性能优化技巧

在实际CTF比赛中,时间就是分数。以下是几个提升爆破效率的技巧:

  1. 提前计算幂次结果:对于固定的底数和模数,可以预计算一些中间结果

    # 预计算2的幂次表 pow2_table = [pow(2, i, p) for i in range(0, 1000000)]
  2. 使用更快的数学库:gmpy2比Python内置的pow函数快10倍以上

    import gmpy2 gmpy2.powmod(2, r, p)
  3. 分布式计算:将任务分配到多台机器上

    # 分布式任务分配示例 def get_task_range(total_workers, worker_id, total_range): chunk = total_range // total_workers start = worker_id * chunk end = (worker_id + 1) * chunk - 1 if worker_id < total_workers - 1 else total_range return start, end
  4. 进度保存与恢复:长时间运行的任务需要断点续传

    def save_progress(current_r, filename='progress.txt'): with open(filename, 'w') as f: f.write(str(current_r)) def load_progress(filename='progress.txt'): try: with open(filename) as f: return int(f.read()) except FileNotFoundError: return 0

优化前后对比

优化措施单线程速度16线程速度内存占用
原始Python50,000次/秒800,000次/秒
使用gmpy2500,000次/秒8,000,000次/秒
预计算表格1,200,000次/秒19,200,000次/秒

在实际测试中,使用全部优化措施的16线程版本可以在5分钟内完成爆破,比原始版本快8倍。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 18:43:06

STM32硬件AES的5个“坑”你踩过几个?从ECB到GCM模式避坑指南

STM32硬件AES开发实战&#xff1a;从ECB到GCM模式的5个关键陷阱解析 第一次接触STM32的硬件AES加速器时&#xff0c;我被它的性能惊艳到了——相比软件实现&#xff0c;加解密速度提升了近20倍。但随之而来的是一连串的"坑"&#xff0c;有些甚至让我调试到凌晨三点。…

作者头像 李华
网站建设 2026/4/18 18:42:28

AssetStudio终极指南:如何轻松提取Unity游戏资源

AssetStudio终极指南&#xff1a;如何轻松提取Unity游戏资源 【免费下载链接】AssetStudio AssetStudio - Based on the archived Perfares AssetStudio, I continue Perfares work to keep AssetStudio up-to-date, with support for new Unity versions and additional impro…

作者头像 李华
网站建设 2026/4/18 18:42:26

7天从麻将新手到策略高手:Akagi智能助手如何改变你的雀魂游戏体验

7天从麻将新手到策略高手&#xff1a;Akagi智能助手如何改变你的雀魂游戏体验 【免费下载链接】Akagi 支持雀魂、天鳳、麻雀一番街、天月麻將&#xff0c;能夠使用自定義的AI模型實時分析對局並給出建議&#xff0c;內建Mortal AI作為示例。 Supports Majsoul, Tenhou, Riichi …

作者头像 李华
网站建设 2026/4/18 18:29:21

Matlab散点图进阶:scatter函数参数详解与实战代码解析

1. scatter函数基础&#xff1a;从零开始绘制散点图 第一次接触Matlab的scatter函数时&#xff0c;我被它强大的定制能力惊艳到了。这个看似简单的绘图工具&#xff0c;实际上藏着无数让数据可视化的魔法。让我们从一个最基本的例子开始&#xff1a; x randn(100,1); % 生成1…

作者头像 李华