Python怎么验证下载的包是否被篡改_使用Hash校验与签名验证
直接 pip install 不足以保证包安全,因PyPI不强制签名且传输/缓存可能被污染;可靠验证需依赖发布者提供的哈希或GPG签名,wheel包仅支持--hash校验,源码包才可能用.asc签名验证。
为什么直接 pip install 不足以保证包安全
PyPI 上的包默认只做基础上传校验,不强制签名;即使官方仓库本身可信,中间传输过程或本地缓存仍可能被污染。单纯比对文件大小或看下载链接是否带 https:// 没用——攻击者可以劫持 DNS 或镜像源,返回恶意轮子(.whl)而不改哈希值。真正可靠的验证必须依赖发布者提供的、可独立验证的哈希或签名。
用 pip download + --hash 验证下载包的 SHA256
这是最轻量、最常用的校验方式,适用于 PyPI 官方发布的包(且维护者填了 project_urls 或 hashes 字段)。关键不是“下载后手动算哈希”,而是让 pip 在下载时就强制比对:
- 先查包的预期哈希:访问
https://pypi.org/pypi/package-name/json,找releases下对应版本的digests.sha256字段(或从项目文档、GitHub release assets 中获取) - 下载并校验:
pip download --no-deps --no-cache-dir --hash=sha256:abc123... requests==2.31.0
,如果哈希不匹配,
pip会报错Hashes are missing或Hash mismatch - 注意:
--hash必须配合--no-deps使用,否则 pip 会尝试解析依赖并忽略校验;且它只校验 wheel 或 sdist 的原始文件,不校验解压后内容
用 gpg 验证 .asc 签名文件(需维护者主动签名)
只有少数严肃项目(如 pip、setuptools)会为源码包(.tar.gz)附带 .asc 签名文件。这不是 PyPI 强制功能,所以不能默认指望有——得先确认项目文档是否提供 GPG 公钥和签名流程。
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
- 下载包与签名:
wget https://files.pythonhosted.org/.../requests-2.31.0.tar.gz
wget https://files.pythonhosted.org/.../requests-2.31.0.tar.gz.asc - 导入发布者公钥(例如从 keys.openpgp.org 搜索 maintainer 邮箱):
gpg --import requests-maintainer.pub
- 验证:
gpg --verify requests-2.31.0.tar.gz.asc requests-2.31.0.tar.gz
,输出含
Good signature from ...才可信 - 常见坑:
.asc文件可能用 detached signature 方式生成,必须同时传入原始包路径;若提示NO_PUBKEY,说明没导入对应公钥,不能跳过
为什么 wheel 包通常不支持签名验证
PEP 427 明确规定 wheel 是“安装友好型分发格式”,不包含签名机制;PyPI 也不为 .whl 提供 .asc 配套。这意味着:哪怕你看到一个包同时提供 .tar.gz 和 .whl,也只有前者可能带签名,后者只能靠 --hash 校验。
更现实的问题是:大多数用户装的是 wheel,而 wheel 的哈希由上传者计算并提交到 PyPI API,如果攻击者已攻陷维护者账号,就能上传恶意 wheel 并填写伪造哈希——此时 --hash 也失效。真正端到端可信,还得依赖 pip 将来的 trust store 支持或项目启用 sigstore(如 python -m pip install --signature-verified 这类仍在实验阶段的功能)。