Composer 2.2+ 的 self-update 默认强制 GPG 签名校验:下载 composer.phar 和 .sig 文件,用内置公钥验证签名,失败则报“Signature mismatch”并中止;-v 可见“Verifying signature”日志,时间偏差会导致“Signature expired”错误。

Composer 自身更新不走加密命令,self-update 本质是下载并原子替换 composer.phar 文件;它默认启用 GPG 签名校验(2.2+),但校验对象是新 phar 文件本身,不是“对命令加密”——这个说法容易误解。
self-update 怎么验证自己下载的 phar 是否被篡改?
从 Composer 2.2 开始,self-update 默认强制校验远程 phar 的 GPG 签名。它会:
- 下载新版
composer.phar和配套的.sig签名文件 - 用内置公钥(来自 https://www.php.cn/link/84e126c81be5b857ebddb2619860007c)验证签名
- 签名不匹配时直接中止,报错
Signature mismatch,不会写入文件
你不需要手动导入密钥,也不需要加参数——只要版本 ≥ 2.2,这就是默认行为。若看到 Updated 但没报错,说明签名已通过。
为什么加了 --no-sigcheck 还能更新成功?
--no-sigcheck 是一个临时绕过开关,仅用于调试或受限网络环境(比如企业防火墙拦截了 .sig 文件)。它不改变 self-update 的本质逻辑,只是跳过签名验证步骤:
- 使用它意味着你主动放弃完整性保障,风险自负
- 常见于国内某些代理环境下,
.sig文件无法下载导致更新卡住 - 生产环境绝不该长期启用;应优先排查网络是否阻断了
https://getcomposer.org/download/下的.sig文件
composer install 时的包完整性校验和 self-update 是两套机制
很多人混淆这两者:self-update 校验的是 Composer 自身可执行文件;而 composer install 校验的是你项目依赖的 dist 包(zip/tar)的 dist.sha256,二者完全独立:
-
self-update不读composer.lock,不碰 vendor,也不触发任何包级哈希比对 - 即使你禁用了
self-update的签名检查(--no-sigcheck),composer install仍会照常校验每个 dist 包的shasum - 反之,如果你关掉了包签名验证(
config security.signature-verification false),也完全不影响self-update的 GPG 校验
如何确认 self-update 真的校验了签名?
最直接的方式是观察输出细节和失败反馈:
- 运行
composer self-update -v(加-v参数),你会看到类似Verifying signature using public key...的日志行 - 故意污染本地时间(比如调快 5 分钟),再运行
self-update,大概率触发Signature expired错误——这是签名验证生效的强信号 - 升级后检查
composer --version输出末尾的 commit hash 和日期,和官网发布页比对,确认不是旧版缓存
真正容易被忽略的是:签名验证依赖系统时间准确性和 HTTPS 链路完整。如果服务器时间偏差过大、或中间有 SSL 中间人设备,self-update 可能静默失败或降级为不校验——别只看“Updated”,要看日志里有没有 Verified 关键字。


















