SharpZipLib(v1.3+)是.NET中唯一主流且可靠的ZIP密码加密方案,支持ZipCrypto和AES-256加密,需正确配置UseZip64、密码编码、路径格式(正斜杠/、相对路径)、UTC时间戳及压缩级别。

用 SharpZipLib 实现 ZIP 密码加密最可靠
标准 .NET 的 System.IO.Compression.ZipFile 不支持密码保护,强行调用会抛出 NotSupportedException。真正能生成带密码 ZIP 的主流方案只有 SharpZipLib(v1.3+),它支持传统 ZIP 加密(ZipCrypto)和更安全的 AES-256 加密。
注意:AES 加密需显式启用,且解压端必须支持 AES(如 7-Zip、WinRAR、macOS 12+ 归档工具),Windows 自带解压器只认 ZipCrypto。
- 安装 NuGet 包:
Install-Package SharpZipLib - 必须引用命名空间:
using ICSharpCode.SharpZipLib.Zip; - 设置密码前必须调用
zipStream.UseZip64 = UseZip64.On;,否则大文件或含中文路径时易出错
ZipOutputStream 设置密码与加密方式
密码不是“设个字符串”就完事——加密方式、密码编码、压缩级别都要协同配置,否则解压失败或报 Bad password。
- ZipCrypto(兼容性好):
zipStream.Password = "mypass";(无需额外设置) - AES-256(推荐):
zipStream.Password = "mypass"; zipStream.Encryption = EncryptionAlgorithm.Aes256; - 密码默认按 ISO-8859-1 编码,若含中文密码,需提前转为字节数组并指定编码:
zipStream.Password = Encoding.UTF8.GetBytes("密码123"); - 压缩级别建议设为
Deflater.BEST_COMPRESSION或Deflater.DEFAULT_COMPRESSION,NO_COMPRESSION会导致部分工具拒绝解压
写入文件时路径处理不当会导致解压后乱码或结构错误
ZIP 规范要求内部路径使用正斜杠 /,且不能以 / 开头;同时要避免绝对路径(如 C:dataile.txt),否则解压可能越权写入系统目录。
- 正确做法:用
Path.GetFileName()或Path.GetRelativePath()提取相对路径,再将替换为/ - 示例:
string entryName = Path.GetRelativePath("C:\src", "C:\src\docs\readme.md").Replace("\", "/");→docs/readme.md - 空目录需手动添加结尾
/(如logs/),否则会被忽略 - 时间戳建议统一设为 UTC,避免跨时区解压显示异常:
zipEntry.DateTime = DateTime.UtcNow;
常见失败现象与定位方向
生成的 ZIP 看似成功但无法解压,多数不是密码错,而是底层协议不匹配。
- WinRAR 提示“CRC failed”或“invalid compressed data” → 检查是否漏设
zipStream.IsStreamOwner = false;(尤其配合FileStream时) - macOS 解压报“Unable to expand archive” → 很可能是用了 AES 但未设
zipStream.UseZip64 = UseZip64.On; - 中文文件名显示为乱码 → 确认没调用
zipStream.SetLevel()以外的编码设置,SharpZipLib v1.3+ 默认 UTF-8,旧版需设zipStream.UseUnicode = true; - 密码正确却提示错误 → 检查目标解压软件是否支持所选加密类型(例如 Windows 资源管理器不支持 AES)
真正难的不是加密码,是让不同系统、不同软件都能一致识别那个“加密上下文”——路径分隔符、编码、Zip64 开关、时间戳、甚至空目录标记,缺一不可。










