某些Zip客户端可读取Zip文件加密,而不是其他人

时间:2015-06-16 19:38:47

标签: objective-c zip zlib

我正在调查我的开源bug report项目中的UnzipKit。基本上,在将使用密码加密的文件写入Zip文件时,某些Zip客户端可以读取生成的存档,而不是其他客户端。

UnzipKit使用围绕zlib的MiniZip包装器将密码写为UTF-8字符串,zlib仅支持"传统PKWare加密"而非AES。 它使用zipOpenNewFileInZip3() MiniZip函数打开文件进行写入。

Mac上的BetterZip和UnzipKit以及Windows上的7zip都可以读取它。但是,WinZip(Mac和Windows)和Mac的unzip命令行应用程序抱怨密码不正确。

出于测试目的,我使用111111作为密码加密文件,如错误报告中所示。我尝试将文本编码更改为ASCII和拉丁语1(CP-1252),但这似乎没有什么区别。

我正在努力熟悉Zip文件的工作方式,但这对我来说似乎仍然很神秘。我有什么办法让它在一些客户而不是其他客户中工作?我希望它能够全面运作或全面破解。

这是一个zip文件的十六进制转储,无法解压缩:

  

50 4B 03 04 14 00 01 00 08 00 B7 54 D1 46 1B B6 2D 32 2F 00 00 00 21 00 00 00 0F 00 00 00 54 65 73 74 20 46 69 6C 65 20 41 2E 74 78 74 37 52 6F F1 31 B6 6E 3D 76 CD 3A 67 0E FF 08 42 C9 4D 61 74 C1 27 DF CB BE 24 41 46 56 60 89 C2 07 97 56 C9 2A 50 80 86 15 E2 62 66 90 77 20 50 4B 01 02 00 00 14 00 01 00 08 00 B7 54 D1 46 1B B6 2D 32 2F 00 00 00 21 00 00 00 0F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 65 73 73 20 46 69 6C 65 20 41 2E 74 78 74 50 4B 05 06 00 00 00 00 01 00 01 00 3D 00 00 00 5C 00 00 00 00 00

这是我在命令行上获得的,返回码为82:

$ unzip -P 111111 PasswordProtected.zip
Archive:  PasswordProtected.zip
   skipping: Test File A.txt         incorrect password

更新

我使用WinZip for Mac创建了相同文件的存档,并在文件上使用相同的密码。这是它的十六进制转储:

  

50 4B 03 04 14 00 03 00 08 00 27 BA 76 44 1B B6 2D 32 2F 00 00 00 21 00 00 00 0F 00 00 00 54 65 73 74 20 46 69 6C 65 20 41 2E 74 78 74 1C 68 5F 1E FF CA 3A 6C D5 B6 01 28 0F 72 83 D9 01 9B BA 87 51 50 1F 66 61 83 43 E8 64 58 B6 ED A6 F0 9B 3B 87 89 70 F2 4F D9 AB 21 6A 6A 06 50 4B 01 02 14 03 14 00 03 00 08 00 27 BA 76 44 1B B6 2D 32 2F 00 00 00 21 00 00 00 0F 00 00 00 00 00 00 00 00 00 00 00 80 81 00 00 00 00 54 65 73 74 20 46 69 6C 65 20 41 2E 74 78 74 50 4B 05 06 00 00 00 00 01 00 01 00 3D 00 00 00 5C 00 00 00 00 00

最大的区别是文件数据完全不同,这意味着它是用不同的密钥加密的。此外,通用位标志表示它使用最大压缩而不是正常压缩。如果其余的提供任何线索,这是差异的摘要,用字段名称provided by the spec注释。

  • 本地文件标题

    Field Name                UnzipKit Bytes  WinZip Bytes
    general purpose bit flag  01 00           03 00
    last mod file time        B7 54           27 BA
    last mod file date        D1 46           76 44
    
  • 档案数据

    UnzipKit
    37 52 6F F1 31 B6 6E 3D 76 CD 3A 67 0E FF 08 42 C9 4D 61 74 C1 27 DF CB BE 24 41 46 56 60 89 C2 07 97 56 C9 2A 50 80 86 15 E2 62 66 90 77 20
    
    WinZip
    1C 68 5F 1E FF CA 3A 6C D5 B6 01 28 0F 72 83 D9 01 9B BA 87 51 50 1F 66 61 83 43 E8 64 58 B6 ED A6 F0 9B 3B 87 89 70 F2 4F D9 AB 21 6A 6A 06
    
  • 中央目录结构

    Field Name                UnzipKit Bytes  WinZip Bytes
    version made by           00 00           14 03
    general purpose bit flag  01 00           03 00
    last mod file time        B7 54           27 BA
    last mod file date        D1 46           76 44
    external file attributes  00 00 00 00     00 00 80 81
    

以下所有字段均为100%:

  • 本地文件标头
    • version to extract
    • compression method
    • crc-32
    • compressed size
    • uncompressed size
    • uncompressed size
    • extra field length
    • file name
  • 中央目录结构
    • version needed to extract
    • compression method
    • crc-32
    • compressed size
    • uncompressed size
    • file name length
    • extra field length
    • file comment length
    • disk number start
    • internal file attributes
    • relative offset of local header
    • file name
  • 整个"中央目录记录的结尾"

1 个答案:

答案 0 :(得分:2)

我猜测zipOpenNewFileInZip3()来电中的最后一个参数为零。它应该是文件的CRC。

当压缩条目被加密时,它前面是一个12字节的加密头。该标题由10或11个随机字节组成,后跟该文件CRC的高端的2或1个字节。然后使用密码对标头进行加密,并从那里继续对压缩数据进行加密。 (1对2字节由zip格式的版本决定。)这允许解压缩程序通过将解密的加密标头的末尾与存储在其之前的本地标头中的CRC进行比较来检查密码。

BetterZip和7Zip发生的事情是他们根本没有检查加密头的末尾。然后,他们没有注意到加密头不符合规范,并继续正确解密压缩数据。另一方面,UnZip和WinZip检测到错误。