PKZIP加密攻击中CRC32()第二个参数pt的作用疑问
PKZIP加密攻击中CRC32调用的疑问解答
问题背景
在优化PKZIP加密攻击方法时,遇到代码key0 = crc32 ( key0, pt );,但我们熟知的标准CRC32函数定义如下:
#define CRC32_POLYNOMIAL 0xEDB88320L uint32_t crc32(const uint8_t *data, size_t length) { uint32_t crc = 0xFFFFFFFF; for (size_t i = 0; i < length; ++i) { crc ^= data[i]; for (int j = 0; j < 8; ++j) { if (crc & 1) { crc = (crc >> 1) ^ CRC32_POLYNOMIAL; } else { crc >>= 1; } } } return ~crc; }
该调用的参数形式和标准函数不符,不仅我,zipcrack的开发者也认为PKZIP官方Appnote文档存在误导。核心疑问点:
- 表达式中
pt的作用是什么? - 标准CRC32要么接收数据+长度,要么是单参数形式,为何这里会出现带"字符参数"的调用?
- 若要在标准代码逻辑中适配这个参数,该char参数的作用是什么?
核心解答
这里的crc32不是标准的一次性CRC计算函数,而是PKZIP加密算法专用的增量式CRC32状态更新函数,和你提供的标准函数属于不同场景的实现:
参数含义
- 第一个参数
key0:是当前的CRC32状态值(对应标准函数循环过程中的crc变量,而非初始的0xFFFFFFFF) - 第二个参数
pt:是单个字节的明文字符(plaintext)
- 第一个参数
实际逻辑
这个调用的作用是:基于当前的CRC状态key0,将单个明文字节pt纳入计算,得到更新后的CRC状态,再赋值回key0——这是PKZIP密钥调度流程中的关键步骤,用于动态更新密钥的CRC分量。和标准函数的适配
如果要把这个逻辑套入你提供的标准代码框架,相当于提取标准函数中单字节处理的核心逻辑,跳过初始值赋值和最终取反步骤,实现如下:uint32_t pkzip_crc32_update(uint32_t current_crc, uint8_t byte) { uint32_t crc = current_crc; crc ^= byte; for (int j = 0; j < 8; ++j) { if (crc & 1) { crc = (crc >> 1) ^ 0xEDB88320L; } else { crc >>= 1; } } return crc; }这就是
key0 = crc32(key0, pt)对应的实际功能。关于Appnote的误导
PKZIP官方Appnote文档对这个CRC调用的描述确实模糊,没有明确说明这是增量式的单字节更新函数,导致很多开发者会和标准CRC32函数混淆,zipcrack等工具的开发者也都对此有过吐槽。
内容的提问来源于stack exchange,提问作者terry franklin
相关产品推荐
相关产品推荐

