ssh2_auth_pubkey_file

(PECL ssh2 >= 0.9.0)

ssh2_auth_pubkey_file使用公钥进行身份验证

描述

ssh2_auth_pubkey_file(
    resource $session,
    string $username,
    string $pubkeyfile,
    string $privkeyfile,
    string $passphrase = ?
): bool

使用从文件中读取的公钥进行身份验证。

参数

session

ssh2_connect() 调用获得的 SSH 连接链接标识符。

username

pubkeyfile

公钥文件需要采用 OpenSSH 格式。它应该类似于

ssh-rsa AAAAB3NzaC1yc2EAAA....NX6sqSnHA8= rsa-key-20121110

privkeyfile

passphrase

如果 privkeyfile 被加密(应该被加密),则必须提供 passphrase

返回值

成功时返回 true,失败时返回 false

示例

示例 #1 使用公钥进行身份验证

<?php
$connection
= ssh2_connect('shell.example.com', 22, array('hostkey'=>'ssh-rsa'));

if (
ssh2_auth_pubkey_file($connection, 'username',
'/home/username/.ssh/id_rsa.pub',
'/home/username/.ssh/id_rsa', 'secret')) {
echo
"公钥身份验证成功\n";
} else {
die(
'公钥身份验证失败');
}
?>

备注

注意:

底层的 libssh 库不支持部分身份验证。也就是说,如果您需要同时提供公钥和密码,则该函数似乎已失败。在这种情况下,此调用的失败可能仅意味着身份验证尚未完成。您需要忽略此失败并继续,然后调用 ssh2_auth_password() 以完成身份验证。

添加备注

用户贡献的备注 11 条备注

Aurelien Marchand
2 年前
我们合作的供应商要求同时使用密码身份验证和公钥/私钥身份验证。

经过大量的痛苦和测试,我们采取了以下措施使其工作,避免了安装 phpseclib 的需要

<?php

$server
= "subdomain.example.com";
$username = "username";
$password = "password";
$path_to_public_key = "file.pub";
$path_to_private_key = "file.priv"; // 关键:权限必须为 0600!!
$path_to_needed_file = "/path/to/file/needed.txt";

$ssh2 = ssh2_connect($server);
@
ssh2_auth_pubkey_file($ssh2,$username,$path_to_public_key,$path_to_private_key); // 这将返回警告,但这是正常的,可以忽略
ssh2_auth_password($ssh2,$username,$password);
$sftp = ssh2_sftp($ssh2);
$file = fopen("ssh2.sftp://" . intval($sftp). $path_to_needed_file,"r");
$content = fread($file,1024);
fclose($file);
ssh2_disconnect($ssh2);

echo
$content;
?>
miloslav dot hula at gmail dot com
4 年前
如果您在使用 RSA 密钥时遇到问题,请检查私钥文件内容是否以

-----BEGIN RSA PRIVATE KEY-----

开头,而不是

-----BEGIN OPENSSH PRIVATE KEY-----

第一个可以通过以下方式创建

ssh-keygen -m PEM -t rsa -f mykey
mrpetovan at gmail dot com
8 年前
注意密钥文件路径中的波浪号 (~),因为它们会在调试版本中触发以下警告

PHP Warning: String is not zero-terminated (ZZZZZZZZZZZZZZZZZZ1wjj*=?<) (source: Zend/zend_execute.h:81) in Unknown on line 0

尽管身份验证将成功。

<?php
$ssh_conn
= ssh2_connect('test.host.com', 22, array('hostkey' => 'ssh-rsa'));
ssh2_auth_pubkey_file($ssh_conn, 'user', '~/.ssh/id_rsa.pub', '~/.ssh/id_rsa')
?>

上面的代码将抛出警告。

<?php
$ssh_conn
= ssh2_connect('test.host.com', 22, array('hostkey' => 'ssh-rsa'));
ssh2_auth_pubkey_file($ssh_conn, 'user', '/home/user/.ssh/id_rsa.pub', '/home/user/.ssh/id_rsa')
?>

上面的代码不会。

如果您想对波浪号进行动态替换,可以使用 posix_getpwuid (https://php.net/manual/en/function.posix-getpwuid.php)
nerak-spelled-backwards at modo dot coop
11 年前
此函数在某些 Linux 安装中存在已知的错误 (https://bugs.php.net/bug.php?id=58573):如果您使用 libgcrypt 编译了 libssh2,则无法加密您的私钥。根据错误页面,解决方案是使用 OpenSSL 重新构建 libssh2。(或者不要加密您的私钥,但这似乎不太负责任。)

这不是错误报告 - 错误显然正在被修复 - 而是对其他人的提示,因为我花了至少一个小时在 Google 上搜索才意识到问题不在我的代码中。
Christophe
3 年前
用户应该注意错误 78661 https://bugs.php.net/bug.php?id=78661

截至 2020 年 12 月,在某些 Linux 发行版(至少包括 debian 10 和 ubuntu 20.04)上,尽管 ssh 守护程序将接受连接,但函数 ssh2_auth_pubkey_file 仍然顽固地报告错误。

我花了几个小时才意识到我的代码是正确的,但函数有 bug。如果你遇到此 bug,可以尝试使用 https://php.net/ssh2_auth_password 代替...... 如果适用。
christian at cvj dot se
12 年前
在我的运行 PHP 的 Linux Debian 服务器与另一台 Linux Debian 服务器通信时,我遇到了 RSA 连接问题。DSA 则可以正常工作。我通过在终端中执行以下操作解决了问题:

* ssh-keygen -t rsa
.... PUBFILE
* ssh-keygen -f PUBFILE -e
OUTPUT

id_rsa.pub =
ssh-rsa OUTPUT [COMMENT]
max
12 年前
嗯,你需要使用以下命令格式化公钥:

# ssh-keygen -f id_rsa.pub -i
输出:"ssh-rsa <YOURKEYDATA>"

这对我有用。
deepakssn@gmailcom
14 年前
设置公钥认证

1. 使用 putty 登录到你要连接的 Unix 服务器。
2. mkdir .ssh(ssh 前面有一个点)
3. cd .ssh
4. ssh-keygen -t rsa mykey
5. 输入测试密码
6. ls -al -> 你会看到两个文件 mykey 和 mykey.pub
7. cat mykey.pub >>authorized_keys
8. cat mykey
9. 将屏幕上的内容复制到记事本并保存为 "c:\mykey"(带引号)
10. cat mykey.pub
11. 将屏幕上的内容复制到记事本并保存为 "c:\mykey.pub"(带引号)

<?php

function my_ssh_disconnect($reason, $message, $language)
{
printf("服务器已断开连接,原因代码为 [%d],消息为:%s\n", $reason, $message);
}

// 打开连接,在发送数据包时强制使用 3des-cbc,在接收数据包时使用任何强度的 aes 密码,双向不压缩,并使用 Group1 密钥交换。
$methods = array(
'kex' => 'diffie-hellman-group1-sha1',
'client_to_server' => array(
'crypt' => 'aes256-cbc',
'comp' => 'none',
'mac' => 'hmac-sha1'),
'server_to_client' => array(
'crypt' => 'aes256-cbc',
'comp' => 'none',
'mac' => 'hmac-sha1'));

$callbacks = array('disconnect' => 'my_ssh_disconnect');

// 在 Unix 服务器上运行命令的函数

function run_cmd($ssh_host, $user_name, $keyfilename, $ssh_command)
{
$connection = ssh2_connect($ssh_host, 22, $methods, $callbacks);
if (!
$connection) die('连接失败');
if (
ssh2_auth_pubkey_file($connection, $user_name, $keyfilename.".pub", $keyfilename, 'test'))
{
echo
"公钥身份验证成功,用户: $user_name";
}
else
{
die(
'公钥身份验证失败');
}

$stream = ssh2_exec($connection, $ssh_command);
$i=0;
stream_set_blocking($stream, true);
$line = stream_get_line($stream, 1024, "\n");
while (!
feof($stream))
{
echo
$line.' ';
$line = stream_get_line($stream, 1024, "\n");
$i++;
}
echo
"计数: ".$i;
flush();
unset(
$stream);
}

function
my_ssh_disconnect($reason, $message, $language)
{
printf("服务器已断开连接,原因代码为 [%d],消息为:%s\n",
$reason, $message);
}

// 主代码

$user_name = "USERID";
$keydir = "c:\\";
$search_string = 'needle';
$keyfilename= $keydir.'mykey';
$ssh_host = "foo.bar.com";
$ssh_command = 'grep "'.$search_string.'" /haystack/*.log';
run_cmd($ssh_host, $user_name, $keyfilename, $ssh_command);

$ssh_command = 'ls -al';
run_cmd($ssh_host, $user_name, $keyfilename, $ssh_command);
?>
anjo2
13 年前
RSA 密钥可能无法正常工作,使用 DSA 密钥兼容性更高

Linux
ssh-keygen -t dsa
cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh/
chmod -R 600 ~/.ssh/*

PHP
<?php
$methods
= array(
'kex' => 'diffie-hellman-group1-sha1',
'hostkey' => 'ssh-dss',
'client_to_server' => array(
'crypt' => '3des-cbc',
'mac' => 'hmac-md5',
'comp' => 'none'),
'server_to_client' => array(
'crypt' => '3des-cbc',
'mac' => 'hmac-md5',
'comp' => 'none'));
$connect = ssh2_connect('127.0.0.1', 22, $methods);
if(
ssh2_auth_pubkey_file($connect, 'username', '~/.ssh/id_dsa.pub', '~/.ssh/id_dsa'))
{
echo
"公钥身份验证成功\n";
}
else
{
echo
"公钥身份验证失败\n";
}
?>
gramo dot gnu at gmail dot com
14 年前
我在使用此函数时遇到了一个令人讨厌的问题,每次我尝试运行它时,它都会返回一个

使用公钥对 <user> 的身份验证失败

但当我尝试直接使用以下命令连接到服务器时:
ssh <user>@<domain>
一切正常......

经过多次尝试后,我意识到本地文件被 apache 用户读取保护(它们存储在 /home/<user>/.ssh 目录中)

因此,如果你也遇到此问题,只需在 apache 可以读取的位置创建一个新目录,并将密钥放在那里。

我的整个操作如下(Linux & Apache 服务器和客户端)

首先,我创建一个 apache 可以读取的目录:

mkdir ~/.newssh_keys
chmod 777 ~/.newssh_keys

(这是一个安全问题,因此你可能需要了解如何更安全地处理它。)

然后,我在本地服务器上创建密钥,选择 ~/.newssh_keys/id_dsa 作为保存密钥的文件

ssh-keygen -t dsa
...
输入保存密钥的文件(/home/<user>/.ssh/id_dsa):~/.newssh_keys/id_dsa
...

然后,我必须更改私钥的权限
(这是一个安全问题,因此你可能需要了解如何更安全地处理它。)

chmod 644 ~/.newssh_keys/id_dsa

我将公钥复制到服务器的 .ssh 目录
client$ scp id_dsa.pub <remoteuser>@<server_domain>:~/.ssh/

然后,我使用传统的 ssh 连接到服务器,以便将公钥追加到 authorized_keys2 文件的末尾

server$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys2

并删除公钥以保持干净
server$ rm ~/.ssh/id_dsa.pub

最后,我在我的 PHP 脚本中使用以下代码:

<?php
// 为了确保 Apache 可以读取公钥
// (调试完成后删除)
$pub_key = file_get_contents('~/.newssh_keys/id_dsa.pub');
print
"<pre>";
var_export($pub_key);
print
"</pre>";

// 为了检查私钥
// (调试完成后删除)
$prv_key = file_get_contents('~/.newssh_keys/id_dsa');
print
"<pre>";
var_export($prv_key);
print
"</pre>";

// 连接代码
$connection = ssh2_connect('<server_domain>', 22, array('hostkey', 'ssh-dss'));
if (
ssh2_auth_pubkey_file($connection, '<server_user>',
'~/.newssh_keys/id_dsa.pub',
'~/.newssh_keys/id_dsa')) {
echo
"公钥认证成功\n";
} else {
echo
"公钥认证失败";
}
?>
tekiedude at gmail dot com
17 年前
这可能非常不安全,但如果你是在封闭的环境中,你可以自担风险运行它。

我试图从服务器 A 获取到服务器 B 的 SSH 访问权限,但服务器 A 运行 Apache 作为 'apache' 用户,
我需要服务器 B 上由 root 拥有的文件。所以我需要一种方法让 Apache 用户以 root 身份连接
到服务器 B。以下是我的操作步骤(两台服务器都运行 Linux - 特别是 CentOS4)

1. ssh-keygen -t rsa -f id_rsa 生成密钥,不设置密码
2. 将 id_rsa.pub 文件追加到服务器 B 的 /root/.ssh/authorized_keys2
3. 将 id_rsa 和 id_rsa.pub 文件复制到像 /var/www/.ssh/ 这样的目录
(恰好是 CentOS 上 Apache 的主目录)
4. chown -R apache.apache /var/www/.ssh

然后你可以像这样连接
$connection = ssh2_connect($server,22,array('hostkey'=>'ssh-rsa'));
if (ssh2_auth_pubkey_file($connection,'root',
'/var/www/.ssh/id_rsa.pub',
'/var/www/.ssh/id_rsa')) {
echo "success!";
}
else
{
echo "no success :-(";
}
To Top