CRC检验错误
pngcheck -v 分析png格式,报错CRC ERROR
对一张正常的图片,通过修改其宽度或者高度隐藏信息,使计算出的CRC校验码与原图的CRC校验码不一致;windows的图片查看器会忽略错误的CRC校验码,因此会显示图片,但此时的图片已经是修改过的,所以会有显示不全或扭曲等情况,借此可以隐藏信息。
而Linux、macOS下的图片查看器不会忽略错误的CRC校验码,因此用Linux打开修改过宽或高的png图片时,会出现打不开的情况
png格式:
前八个字节
89 50 4E 47 0D 0A 1A 0A
为png的文件头,
该段格式是固定的
前四个字节00 00 00 0D(即为十进制的13)代表数据块的长度为13,数据块包含了png图片的宽高等信息,该段格式是固定的
之后的四个字节49 48 44 52(即为ASCII码的IHDR)是文件头数据块的标示,该段格式也是固定的
数据块格式(十三字节):
- 00 00 05 8C 该四字节为图片的宽,该段数据是由图片的实际宽决定的
- 00 00 01 f4( 00000406原图)该四字节为图片的高,该段数据是由图片的实际高度决定的
- 后五字节08 06 00 00 00 凑满十三字节,数据块
再往后四位是CRC校验码94F3FED1
校验码是由IHDR文件头标示与宽高共同计算出来的所以,一旦修改高或宽,便不符合校验码了,就会出错
爆破,找出正确的高
可以选择爆破的方法,找出修改前的高度来匹配CRC校验码,用正确的宽高修复
# -*- coding: utf-8 -*-
import binascii
import struct
#\x49\x48\x44\x52\x00\x00\x02\xA7\x00\x00\x01\x00\x08\x06\x00\x00\x00
crc32key = 0x6D7C7135
for i in range(0, 65535):
height = struct.pack('>i', i)
#CRC: 6D7C7135
#把height的位置留出来,data减去四字节
data = '\x49\x48\x44\x52\x00\x00\x02\xA7' + height + '\x08\x06\x00\x00\x00'
crc32result = binascii.crc32(data) & 0xffffffff
if crc32result == crc32key:
print ''.join(map(lambda c: "%02X" % ord(c), height))