我正在尝试实现.ZIP文件格式规范(https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)第6.1节中描述的“传统PKWARE解密”,但结果不符合预期。
为了测试,我使用的是一个没有压缩的TUGZip压缩的小文本文件。
原始文件的CRC-32为 0x7259B728 。
.ZIP文件中的12字节“加密标头”包含E6-8B-FE-EB-40-28-E1-55-4E-44-28-E0
'密码'是61-7A-62-79-63
(azbyc)。
解密后的加密标头包含C3-7D-EE-4C-11-B3-39-A3-97-55-21-B3
规范的第6.1.6节说:
“在解密标头之后,缓冲区中的最后1或2个字节应该是正在解密的文件的CRC的高位字/字节....”
所以我期待0x72,但我得到0xB3。
据我所知,我完全遵循了规范,但我仍然是C的新手,所以我在C#中重新创建了程序,并得到了相同的结果。我显然缺少或误解了一些东西。任何帮助将不胜感激。
提前谢谢。
zip.c
//struct ZIP_INFO contains member 'uint32_t *keys'
//
//At initialisation, the values are:
//keys[0] = 0x12345678
//keys[1] = 0x23456789
//keys[2] = 0x34567890
unsigned char zip_decrypt_byte(uint32_t *keys)
{
uint16_t u = (uint16_t)((keys[2] & 0xFFFF) | 0x02);
return (unsigned char)(((u * (u ^ 0x01)) >> 8) & 0xFF);
}
void zip_decrypt_bytes(ZIP_INFO *info, unsigned char *buf, size_t len)
{
unsigned char *u = buf;
while (len--)
{
*u ^= zip_decrypt_byte(info->keys);
zip_update_keys(info->keys, u++);
}
}
void zip_set_password(ZIP_INFO *info, unsigned char *password, size_t len)
{
unsigned char *u = password;
while (len--)
zip_update_keys(info->keys, u++);
}
void zip_update_keys(uint32_t *keys, unsigned char *c)
{
unsigned char u;
keys[0] = crc_32(keys[0], c, 1);
keys[1] += (keys[0] & 0xFF);
keys[1] = ((keys[1] * 134775813) + 1);
u = (unsigned char)((keys[1] >> 24) & 0xFF);
keys[2] = crc_32(keys[2], &u, 1);
}
crc.c
static uint32_t crc_table[256];
uint32_t crc_32(uint32_t crc, unsigned char *buf, size_t len)
{
unsigned char *p;
crc ^= 0xFFFFFFFF;
p = buf;
while (len--)
crc = (crc_table[((crc ^ *p++) & 0xFF)] ^ (crc >> 8));
return (crc ^ 0xFFFFFFFF);
}
void crc_initialise()
{
uint32_t u0, u1, u2;
for (u0 = 0; u0 < 256; u0++)
{
u1 = u0;
for (u2 = 0; u2 < 8; u2++)
{
if (u1 & 0x01)
u1 = ((u1 >> 1) ^ 0xEDB88320);
else
u1 >>= 1;
}
crc_table[u0] = u1;
}
}
'test.zip'的内容
50-4B-03-04-14-00-01-00-00-00-F9-1E-55-47-28-B7-59-72-2B-00-00-00-1F-00 -00-00-08-00-00-00-74-65-78-74-2E-74-78-74-E6-8B-FE-EB-40-28-E1-55-4E-44-28 -E0-15-8E-13-49-CD-B0-B7-E4-43-40-9D-BA-5D-41-A8-BD-EA-47-07-AD-0E-4A-2F-BA -BD-1F-55-94-D3-6E-77-50-4B-01-02-14-00-14-00-01-00-00-00-F9-1E-55-47-28-B7 -59-72-2B-00-00-00-1F-00-00-00-08-00-00-00-00-00-00-00-01-00-20-00-00-00-00 -00-00-00-74-65-78-74-2E-74-78-74-50-4B-05-06-00-00-00-00-01-00-01-00-36-00 -00-00-51-00-00-00-00-00