Composer不生成自签名证书,只消费证书;需更新私有仓库服务端证书,并通过ssl.cafile显式配置PEM格式根证书路径,确保PHP进程可读、顺序正确(中间CA→根CA)、且与服务端证书严格对应。

Composer 本身不生成、不更新 HTTPS 协议的自签名证书——它只消费证书(用于验证私有仓库的 TLS 连接)。你要更新的不是 Composer 的证书,而是你私有仓库服务端使用的自签名证书,以及 Composer 客户端信任它的配置方式。
为什么 composer install 报 cURL error 60 且新证书仍不生效
常见现象是:你已用 openssl 或 dotnet dev-certs 重新生成了服务端证书,也把新根证书导入了系统(如 Windows 信任根存储),但 composer install 依旧失败。
根本原因在于:Composer 不读取系统证书存储(Windows CryptoAPI / macOS Keychain),它只认 OpenSSL 能加载的 PEM 文件路径,且该路径必须通过 ssl.cafile 显式指定。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 旧证书文件(如
/path/to/old-root.pem)还被composer config --global ssl.cafile指向,没换 - 新证书是 DER 格式(
.cer)或带 BOM 的文本,未转为纯 PEM;openssl x509 -in new.crt -text -noout执行报错即说明格式不对 - 合并证书链时顺序错误:必须是「中间 CA → 根 CA」,不能颠倒;若无中间 CA,只放根 CA 即可
- PHP 进程(如 CLI 下的
php或php-fpm)无权读取新证书文件,尤其当路径在用户家目录而 web 服务以www-data运行时
如何让 Composer 信任新生成的自签名根证书
关键动作是更新 ssl.cafile 配置,并确保其指向一个合法、可读、内容正确的 PEM 文件。
- 确认新根证书是 PEM 格式:以
-----BEGIN CERTIFICATE-----开头,结尾为-----END CERTIFICATE-----;如果不是,用openssl x509 -inform DER -in root.cer -outform PEM -out root.pem转换 - 如果私有仓库用了中间 CA,用
cat intermediate.pem root.pem > trusted-ca-chain.pem合并(注意顺序!);别用记事本拖拽拼接 - 全局设置新路径:
composer config --global ssl.cafile /etc/ssl/certs/my-new-root.pem(Linux/macOS)或composer config --global ssl.cafile C:\certs\my-new-root.pem(Windows) - 验证是否生效:
composer config --global ssl.cafile应输出你刚设的路径;再执行composer diagnose,看 “CA file” 行是否显示 “OK”
Composer 2.5+ 用户特别注意:ssl.cafile 加载逻辑变了
≥2.5 版本不再简单透传给 cURL,而是先尝试用该文件初始化 OpenSSL 上下文。一旦路径错、权限不足、或 PEM 解析失败,它会静默 fallback 到系统默认 CA 路径——这意味着你改了配置却没效果,错误信息还是老样子。
- 检查 PHP 是否能读该文件:
php -r "echo file_get_contents('/etc/ssl/certs/my-new-root.pem') ?: 'fail';",若报错说明权限或路径问题 - 确认 PHP 使用的 OpenSSL 版本支持你的证书算法(如 ECDSA 证书需 OpenSSL ≥1.1.1);运行
php -i | grep -i openssl查看版本和openssl.cafile值 - 若你在 CI/CD 中使用容器,确保证书文件已 COPY 进镜像,且
composer config --global在构建阶段执行,而非仅在本地运行
最易被忽略的一点:证书更新后,必须同时更新服务端(Nginx/Apache 的 ssl_certificate 和 ssl_certificate_key)和客户端(Composer 的 ssl.cafile)——两者缺一不可,且 PEM 内容必须严格对应。任何一端滞后,都会导致握手失败,而错误提示永远只会说“SSL certificate problem”。

















