PHP使用PuTTY .ppk密钥文件认证SFTP服务器的问题求助
Hey,我来帮你解决这个SFTP认证的问题!你遇到的核心卡点是PPK格式的密钥没法直接被PHP的ssh2扩展识别——因为ssh2只认OpenSSH标准格式的密钥,而PPK是PuTTY/WinSCP专属的格式。下面我一步步给你讲清楚怎么处理:
第一步:把PPK密钥转换成OpenSSH格式
你需要把WinSCP用的PPK文件,转换成OpenSSH兼容的私钥和公钥,有两种简单的方法:
- 用WinSCP直接导出:打开WinSCP并成功登录远程服务器后,点击顶部菜单栏的
工具 > 导出OpenSSH密钥,选择你的PPK文件,输入密钥短语(如果设置了的话),选择保存路径就能得到OpenSSH格式的私钥文件(通常命名为id_rsa)。 - 用PuTTYgen转换:打开PuTTYgen工具,点击
加载选择你的PPK文件,输入密钥短语解锁后,点击Conversions > Export OpenSSH key保存私钥;同时,PuTTYgen窗口里Public key for pasting into OpenSSH authorized_keys file栏的内容,就是对应的公钥,把这段内容复制出来保存成id_rsa.pub文件即可。
第二步:明确认证所需的公钥和私钥
- 私钥:就是你转换后得到的OpenSSH格式私钥文件(比如
id_rsa),这个文件是敏感信息,要确保权限设置严格(Linux下建议设为600,只有所有者可读可写)。 - 公钥:转换后得到的
id_rsa.pub文件,或者PuTTYgen里复制的那段公钥内容——既然你能用WinSCP登录,说明远程服务器的~/.ssh/authorized_keys文件里已经存在这个公钥了,不需要额外配置。
第三步:PHP ssh2_auth_pubkey_file()的正确用法
先确认你的PHP已经安装并启用了ssh2扩展(可以用phpinfo()检查),然后参考下面的完整代码示例:
<?php $host = '远程服务器IP'; $port = 22; $username = '你的用户名'; // 替换成你转换后的OpenSSH密钥路径 $privateKeyPath = '/var/www/html/keys/id_rsa'; $publicKeyPath = '/var/www/html/keys/id_rsa.pub'; $passphrase = '你的密钥短语'; // 如果没有设置短语,就传空字符串'' // 建立SSH连接 $conn = ssh2_connect($host, $port, array('hostkey' => 'ssh-rsa')); if (!$conn) { die('无法连接到远程服务器,请检查IP和端口'); } // 执行公钥认证 $authSuccess = ssh2_auth_pubkey_file( $conn, $username, $publicKeyPath, $privateKeyPath, $passphrase ); if ($authSuccess) { echo '认证成功!现在可以进行SFTP操作'; // 开启SFTP会话并执行上传示例 $sftp = ssh2_sftp($conn); $localFile = '/path/to/local/test.txt'; $remoteFile = '/remote/server/path/test.txt'; if (ssh2_scp_send($conn, $localFile, $remoteFile, 0644)) { echo '<br>文件上传成功'; } else { echo '<br>文件上传失败'; } } else { die('认证失败,请检查密钥路径、用户名或密钥短语是否正确'); } ?>
备选方案:用phpseclib直接读取PPK
如果你不想转换密钥格式,可以用纯PHP实现的phpseclib库,它支持直接解析PPK文件,不需要依赖ssh2扩展。先通过Composer安装:
composer require phpseclib/phpseclib
然后参考示例代码:
<?php use phpseclib3\Net\SFTP; use phpseclib3\Crypt\RSA; $sftp = new SFTP('远程服务器IP'); // 直接加载PPK密钥 $key = RSA::load(file_get_contents('/path/to/your/key.ppk')); $key->setPassword('你的密钥短语'); if (!$sftp->login('你的用户名', $key)) { die('登录失败,请检查信息是否正确'); } // 上传文件示例 $sftp->put('/remote/path/test.txt', '/local/path/test.txt'); echo '文件上传成功'; ?>
内容的提问来源于stack exchange,提问作者Help
相关产品推荐
相关产品推荐

