go标准库archive/zip不支持解密aes或zipcrypto加密的zip文件,必须使用第三方库如github.com/mholt/archiver/v4,其需在open时传入password选项,且支持winrar传统加密和7-zip aes-256加密。

Go 解压带密码的 ZIP 文件需要第三方库
标准库 archive/zip 完全不支持解密 AES 或传统 PKZIP 加密(ZipCrypto)的 ZIP 文件。你直接用它读取加密 ZIP,会遇到 zip: not a valid zip file 或 zip: invalid checksum ——不是文件损坏,是它根本没实现解密逻辑。
目前稳定可用的方案只有 github.com/mholt/archiver/v4(推荐)或更底层的 github.com/alexmullins/zip(需手动处理密钥派生)。前者封装好、API 直观;后者更轻但得自己调 zip.Decrypt 和 PBKDF2。
实操建议:
- 用
go get github.com/mholt/archiver/v4安装 - 密码必须在打开
*zip.ReadCloser前传入,不能事后设置 - 密码错误时,
archiver.Zip.Read通常返回zip: decryption password incorrect,而非静默失败
用 archiver/v4 解压带密码 ZIP 的最小可行代码
核心是把密码通过 archiver.Zip.Password 选项注入解压流程,且必须在 archiver.Zip.Open 时传入。漏掉这步,哪怕 ZIP 本身能打开,解压文件内容时也会 panic 或返回空数据。
示例:
package main
import (
"github.com/mholt/archiver/v4"
)
func main() {
z := archiver.Zip{
Password: "your_password_here", // ⚠️ 必须设在这里
}
err := z.Extract("secret.zip", "./output")
if err != nil {
panic(err) // 常见错误:zip: decryption password incorrect
}
}
注意点:
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
-
Password字段只对 ZIP 格式有效,对 7z/RAR 不起作用 - 如果 ZIP 是用 WinRAR 用“传统加密”(ZipCrypto)打的,
archiver/v4支持;如果是 7-Zip 用 AES-256 加密的,也支持(它底层用了alexmullins/zip) - 路径中含中文名时,确保 ZIP 创建时用了 UTF-8 flag(现代工具默认开),否则文件名会乱码
为什么不用 crypto/aes 手动解密再解压?
理论上可行,但实际极难落地:PKZIP 加密不是裸 AES-CBC。它混合了 CRC、salt、多次 MD5/PBKDF2 迭代(取决于压缩工具),且每个文件有独立的加密头和初始化向量。WinZip、7-Zip、macOS 归档工具实现细节还不完全一致。
你得反向实现整个密钥派生流程 + 头部解析 + 流式解密 + 校验还原,比调一个封装好的库多出 300+ 行易出错代码。除非你在做安全审计或兼容性测试,否则不值得碰。
所以结论很直接:
- 别自己造 ZIP 解密轮子
- 别尝试用
crypto/aes+archive/zip拼凑 - 接受
archiver/v4的依赖,它已覆盖绝大多数真实场景
解压后文件权限丢失?这是 ZIP 规范限制
ZIP 格式本身不存储 Unix 权限(如 0755),只存 DOS 属性位(只读、隐藏等)。所以无论用 Go 还是 unzip 命令,Linux/macOS 下解压出来的文件默认是 0644 或 0755(由 Go 的 os.FileMode 默认策略决定),不会还原原始 chmod 设置。
如果你依赖权限位(比如解压出可执行脚本),必须额外处理:
- 解压后遍历输出目录,按文件后缀或命名规则
os.Chmod(例如匹配*.sh就设0755) - 改用
tar.gz+golang.org/x/crypto/ssh/terminal实现密码保护,它原生保留权限 - 接受现状:ZIP 就不是为 Unix 权限设计的归档格式
这个限制和语言无关,是 ZIP 规范本身的盲区,容易被忽略,但会影响自动化脚本行为。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










