composer如何验证签名_composer package signing验证【可信】

1次阅读

composer默认不验证包体gpg签名,仅通过https+tls证书+composer.lock中sha-256哈希比对三层机制保障完整性;唯一启用gpg的场景是packagist元数据签名验证(需composer≥2.2且配置signing-key),用于防仓库投毒。

composer如何验证签名_composer package signing验证【可信】

Composer 默认不验证包体 GPG 签名,只校验 SHA-256 哈希和 https 传输链

Composer 本身**不会对每个下载的 .zip/.tar 包执行 GPG 解签名**——它不内置 GPG 引擎,也不要求包作者上传 .sig 文件。所谓“签名验证”,实际是三层防御:HTTPS 连接加密 + 服务器证书可信(TLS 验证)+ composer.lock 中记录的 dist.shasum 哈希比对。这三者缺一不可,但都不是传统意义的“数字签名”。

  • 运行 composer install 时,Composer 会自动读取 composer.lock 里的 "shasum": "a1b2c3...",并和远程 zip 包的实际 SHA-256 值比对;不一致就报错 Signature mismatch, package is corrupted
  • TLS 验证由 src/Composer/Util/TlsHelper.php 执行,依赖 PHP 的 OpenSSL 扩展和系统 CA 证书库;若证书异常(如自签名),会直接中断连接
  • Packagist 的元数据(packages.json)自 2021 年起支持 GPG 签名,但需 Composer ≥ 2.2 且启用 signing-key 配置才触发校验——默认未开启

如何启用 Packagist 元数据 GPG 签名验证(防仓库投毒)

这是目前 Composer 生态中唯一真正用到 GPG 的签名验证场景,目标是防止攻击者篡改 Packagist 的包索引,把恶意包混进搜索结果。它不校验包内容,只校验索引文件本身是否被 Packagist 私钥签署过。

  • 确认版本:composer --version 输出必须 ≥ 2.2.0
  • 设置全局配置:composer config --global signing-key https://packagist.org/keys.json(该 URL 返回的是 Packagist 官方公钥列表)
  • 确保 secure-http: truedisable-tls: falsecomposer.json 或全局 config 中生效
  • 验证是否生效:删掉 vendor/composer.lock,运行 composer install -v,观察日志中是否出现 Verifying packages.json signature with key ...

注意:keys.json 是动态更新的,Composer 不会自动轮换密钥;如果某天 Packagist 更换主密钥,旧版 Composer 可能因找不到对应公钥而拒绝加载包列表。

想验证具体包的 git 标签签名?得绕开 Composer 自己动手

Composer 对 Git 仓库(VCS 类型依赖)只做克隆和检出,**不调用 git tag -v**。如果你真关心某个包是否由作者用 GPG 签过 tag(比如 v2.5.0),就得手动操作:

  • 先从 composer show vendor/package 查看源地址,或翻 composer.locksource.url 字段
  • git clone 拉下仓库,再运行 git tag -v v2.5.0;输出含 Good signature from "Name <email>"</email> 且密钥已导入本地 GPG 环境才算可信
  • composer.json 中显式指定带签名的 tag:"dev-master#v2.5.0""2.5.0"(前提是 minimum-stability 设为 stable
  • 别依赖 dev-maindev-develop —— 这些分支头提交几乎从不签名

常见失效场景和排查路径

很多人以为“开了 HTTPS 就等于安全”,结果还是栽在细节上。最常踩的坑不是技术不会用,而是没意识到验证链条在哪断了。

  • composer install 没报错 ≠ 包没被篡改:如果项目没提交 composer.lock,或用了 --ignore-platform-reqs 跳过哈希检查,那 dist.shasum 校验根本不会触发
  • 私有仓库用 HTTP?"secure-http": true 会直接拒绝加载,错误是 Repository ... is not secure,不是证书问题
  • 自签名证书环境(如内网 gitlab),必须配置 composer config --global cafile /path/to/cert.crt,否则 TLS 验证失败,连包列表都拉不下来
  • CI 环境里 openssl.cafile 没配对?PHP CLI 和 Web SAPI 的 php.ini 常是两套,php -r "print_r(openssl_get_cert_locations());" 可查实际路径

真正关键的不是“有没有签名”,而是你清楚每一步校验发生在哪、谁负责执行、失败时抛什么错。包来源可信这件事,从来不是按一个按钮就能解决的。

text=ZqhQzanResources