* 几天前(文章是2月底写完的),WinRAR曝出一个存在了19年的安全漏洞,实验室的@浮萍大佬在第一时间进行了复现分析,其中用一个非常巧妙的方法获取了修改后的CRC值。通过常规CRC-32算法 (zip和gzip通用) 计算后得到的值与它并不一致,这让我感到十分好奇。遗憾的是,在随后圈里刮起的分析预警风里,也没能发现一篇满足我好奇心的。算了,还是自己动手吧。
CRC基础
CRC,Cyclic Redundancy Check (循环冗余校验) ,是一个根据网络数据包或文件等数据生成固定长度校验码的散列算法,通常用于网络传输、解压缩等过程中的数据正确性校验。
常见的CRC算法有CRC-8、CRC-12、CRC-16和CRC-32,及各种衍生版本,它们主要的不同在于校验码长度和几个决定运算结果的参数上。
本文以CRC-32为主。
一计算过程
CRC的计算和校验中除了上面提到的参数之外,还有几种不同的算法实现。这些概念理论较多篇幅较大,如果有必要再另写文章讨论细节,这里就暂时先跳过了。
不过简单的说,就是通过生成多项式 (见下面生成多项式章节) 对原始数据进行模2除,所得余数即CRC校验码。校验方拿到原始数据和CRC校验码,将CRC校验码补入原始数据之后组成待校验数据 (该过程也可在发送数据之前完成) ,再利用相同的生成多项式对待校验数据模2除,判断所得余数是否为0,是则表示与原始数据一致。
其中,模2除与算术除的区别是,它使用异或运算代替减运算降低了运算