You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Ubuntu从18.04到22.04后,PHP脚本SSH指纹验证不匹配但终端SSH连接正常的问题咨询

升级Ubuntu从18.04到22.04后,PHP脚本SSH指纹验证不匹配但终端SSH连接正常的问题咨询

嗨,这个问题我之前帮朋友排查过类似的,核心原因大概率是PHP ssh2扩展在版本升级后,ssh2_fingerprint()函数的默认输出格式变了,而非远程服务器的公钥指纹真的变了,咱们一步步拆解来看:

问题根源分析

  • 你之前在Ubuntu 18.04+PHP7.2环境下,搭配的是较旧版本的php-ssh2扩展,依赖的libssh2库版本也偏低。当时调用ssh2_fingerprint($session, SSH2_FINGERPRINT_SHA1)返回的是带冒号分隔的十六进制字符串(比如aa:bb:cc:dd:ee:...),这和终端ssh命令默认显示的SHA1指纹格式完全一致。
  • 升级到Ubuntu 22.04+PHP8.1后,php-ssh2扩展依赖的libssh2库版本大幅更新,此时仅传入SSH2_FINGERPRINT_SHA1参数时,函数默认返回的是不带冒号的纯十六进制字符串(比如aabbccddee...)。这就导致你之前存储的旧指纹(带冒号)和新返回的指纹格式不匹配,触发了验证错误——但远程服务器的公钥其实根本没动,所以终端SSH连接的指纹显示完全正常。

解决方案(二选一即可)

  1. 调整PHP代码,统一指纹格式
    如果你想保留之前存储的指纹格式,只需要在调用ssh2_fingerprint()时额外传入SSH2_FINGERPRINT_HEX参数,强制返回带冒号的格式:

    $fingerprint = ssh2_fingerprint($session, SSH2_FINGERPRINT_SHA1 | SSH2_FINGERPRINT_HEX);
    

    这样就能直接和你之前存储的指纹匹配,不需要修改任何存储值。

  2. 转换现有存储的指纹格式
    如果你不想改动代码,可以把存储的旧指纹去掉所有冒号,转换成纯十六进制字符串。比如把aa:bb:cc:dd改成aabbccdd,就能和新函数返回的格式对齐。

快速验证方法

你可以临时在脚本里打印当前返回的指纹,再和终端获取的指纹对比确认:

  • 终端获取不带冒号的SHA1指纹:
    ssh-keygen -lf <(ssh-keyscan 你的远程主机地址 2>/dev/null) | grep SHA1 | awk '{print $2}' | sed 's/SHA1://'
    
  • 终端获取带冒号的SHA1指纹:
    ssh-keygen -lf <(ssh-keyscan 你的远程主机地址 2>/dev/null) | grep SHA1 | awk '{print $2}' | sed 's/SHA1://' | sed 's/../&:/g' | sed 's/:$//'
    
    把这些结果和PHP脚本输出的指纹对比,就能直观看到格式差异啦。

备注:内容来源于stack exchange,提问作者cazort

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 12:29:38