PHPSeclib公钥认证本地运行正常 部署到Plesk服务器后报SSH_MSG_USERAUTH_FAILURE
问题根因分析
- PHP版本兼容问题:phpseclib 3.0要求PHP版本>=5.6.1,你项目composer.json配置的PHP>=5.3约束,会导致composer自动安装适配低版本PHP的依赖包,其中负责签名编码的paragonie/constant_time_encoding包低版本在PHP<5.6环境下运行逻辑异常,生成的公钥签名格式不符合SSH服务端要求,直接返回认证失败。就算本地打包依赖上传到服务器,只要服务器运行脚本的PHP版本低于5.6.1,依然会触发该问题。
- Plesk环境多版本PHP调用不一致:Plesk默认存在多版本PHP共存的情况,如果你用cli执行脚本,默认调用的是系统低版本PHP,就算站点配置了高版本PHP,cli运行时依然会触发兼容问题。
- 原有依赖冲突:项目原有适配PHP5.3的依赖包,和phpseclib 3.0要求的依赖版本冲突,composer自动降级了相关依赖包,导致加密编码逻辑异常。
不修改原有composer配置的解决方案
- 方案1:替换为phpseclib 2.x版本
phpseclib 2.x版本要求PHP>=5.3,完全适配你现有项目的PHP版本约束,公钥认证逻辑和3.x几乎一致,仅需做少量调整:- 将composer.json中phpseclib版本改为
"phpseclib/phpseclib": "^2.0" - 代码命名空间从
phpseclib3改为phpseclib,密钥加载类从PublicKeyLoader替换为Crypt_RSA即可,核心认证逻辑不需要修改,本地测试正常后直接上传到服务器即可正常运行。
- 将composer.json中phpseclib版本改为
- 方案2:指定Plesk高版本PHP运行
如果必须使用phpseclib 3.0,不需要修改服务器composer配置,本地用>=5.6.1版本的PHP安装依赖后打包上传到服务器,运行脚本时指定Plesk自带的高版本PHP路径即可:
Plesk的PHP版本默认存放在/opt/plesk/php/[版本号]/bin/php路径下,比如用PHP7.4运行脚本的命令为/opt/plesk/php/7.4/bin/php your_script.php,web请求则直接在Plesk站点设置中将PHP版本调整为>=5.6.1即可,不需要修改composer里的PHP版本限制。 - 方案3:独立隔离安装依赖
如果担心影响原有项目依赖,可单独下载phpseclib及其所有依赖到一个独立目录,在脚本顶部通过set_include_path()将该独立目录加到加载路径的最前面,优先加载独立目录内的依赖,完全不会影响原有composer的配置和已安装的依赖。
内容的提问来源于stack exchange,提问作者DevelJoe
相关产品推荐
相关产品推荐

