签名验证失败的真实原因是系统时间偏差>5分钟、CA证书过期或镜像未同步新签名/哈希值;须用php -r和curl命令交叉验证时间与证书,再检查镜像是否停服,最后同步删除vendor和composer.lock并切回官方源重装。

签名错误不是镜像“不兼容”,而是本地环境与镜像源之间的时间、证书或元数据信任链断开了——必须逐层验证,不能只换源或清缓存。
检查系统时间是否偏差超过5分钟
Composer 2.2+ 使用 JWT 校验 Packagist 元数据签名,时间戳偏差 >5 分钟会直接拒绝响应,报 Signature verification failed。
- 运行
php -r "echo time() . "\n"; echo date('c');"查看 PHP 当前时间 - 对比系统时间(
date或 Windows 时间设置),误差超 5 分钟就需同步:Linux/macOS 执行sudo ntpdate -s time.apple.com或timedatectl set-ntp true;Windows 在“日期和时间设置”中启用自动同步 - 注意:Docker 容器内时间可能独立于宿主机,需在
docker run中加--network=host或挂载宿主机时间:-v /etc/localtime:/etc/localtime:ro
确认 PHP 使用的 CA 证书是否过期
若 curl -I https://packagist.org/packages.json 报 SSL certificate problem,但浏览器能打开,大概率是 OpenSSL 信任链里还含已吊销的 DST Root CA X3。
- 查证书路径:
php -r "print_r(openssl_get_cert_locations());",重点看default_cert_file是否存在且可读 - 打开该文件(如
/usr/lib/ssl/certs/ca-certificates.crt),搜索DST Root CA X3—— 若存在且签发时间早于 2022 年 9 月,必须更新 - 更新方式:Ubuntu/Debian 运行
sudo apt update && sudo apt install --reinstall ca-certificates;macOS Homebrew 用户执行brew reinstall ca-certificates
验证镜像是否已同步新签名或哈希值
阿里云、腾讯云等镜像同步有 10–30 分钟延迟。你 composer.lock 里存的是旧 dist.sha256,镜像却已更新 dist 包,校验必然失败。
- 别只删
vendor/或只跑composer update—— 前者仍按旧 lock 校验,后者默认复用 lock 不刷新哈希 - 必须同步删除:
rm -rf vendor composer.lock(Windows:rd /s /q vendor & del composer.lock) - 删完后切回官方源重装:
composer config -g --unset repos.packagist && composer config -g repo.packagist composer https://packagist.org && composer clear-cache && composer install - 成功后再决定是否切回镜像(建议等满 30 分钟,或优先选华为云:
https://mirrors.huaweicloud.com/repository/php/)
检查 allow-plugins 配置是否匹配插件名
即使签名通过,插件也可能静默失效:Composer 2.2+ 默认拦截所有插件,allow-plugins 是硬性开关,拼错、漏写、用通配符都会导致后续校验中断。
- 项目级必须在根
composer.json中显式声明:"allow-plugins": ["vendor/plugin-name"],大小写敏感,不可写成Vendor/Plugin-Name或* - 全局配置(
~/.composer/config.json)中若未包含该插件,composer install会直接中断并提示Plugin installation failed - 若插件来自私有源,还需确保其
composer.json中type字段为composer-plugin,且require的依赖真实存在
最易被忽略的是:时间偏差和证书问题不会报具体字段,只会笼统显示 Signature verification failed;而镜像同步延迟引发的 checksum verification failed 看似是网络问题,实则是 lock 文件与远端元数据不一致——这两类错误现象高度相似,但修复路径完全不同,必须靠命令交叉验证,不能凭经验跳步。


















