3

我正在使用libssh2使网络程序更安全。

我希望我的程序以与 OpenSSH 客户端 ssh(1) 尽可能相似的方式进行身份验证。OpenSSH 客户端只会询问服务器实际接受的密钥的密码。

正如我从这个链接中了解到的,一个 ssh 客户端发送一个使用公钥的请求,如果被接受,它可以使用密码解锁私钥。

libssh2 提供了一个函数libssh2_userauth_publickey_fromfile,它接受私钥和公钥文件名和密码。使用此功能非常简单,但这意味着我必须获取私钥的密码,即使服务器一开始就不会接受公钥。对于拥有许多不同密钥的用户来说,这显然是一个问题(我的程序目前遍历 ~/.ssh 目录中的密钥文件)。

我已经尝试阅读libssh2函数的手册页,如果没有更详细的 ssh 协议知识,它们中的大多数看起来太简短了,我无法理解。事实上,其中一些甚至还没有写出来。

谁能告诉我如何只提示 ssh 服务器实际接受的密钥的密码libssh2

4

1 回答 1

4

在 RTFM 并进行一些测试之后,我发现这libssh2_userauth_publickey_fromfile将返回不同的错误代码,具体取决于服务器不接受密钥还是密码不正确。

所以,这是一个非常低效的解决方案(因为它调用libssh2_userauth_publickey_fromfile协议的所有密钥交换部分至少两次)。

int nAttempts = 3; // number of attempts the user gets at entering the passphrase

// Try authenticating with an empty passphrase
int err = libssh2_userauth_publickey_fromfile(session, user, pub, priv,"");
if (err == 0)
{
    fprintf(stderr, "You shouldn't use keys with an empty passphrase!\n");
}
else if (err == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED)
{
    // if we get here it means the public key was initially accepted
    // but the private key has a non-empty passphrase
    char p[BUFSIZ];

    for (int i = 0; i < nAttempts; ++i)
    {
         get_passphrase(p); // assume this gets the passphrase
         err = libssh2_userauth_publickey_fromfile(session, user, pub, priv,p);
         if (err != LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) break;
    }
}

if (err != 0)
{
    fprintf(stderr, "Authentication using key %s failed!\n", priv);
}

为了完整起见,该get_passphrase函数使用此问题的解决方案来提示用户输入密码。

于 2013-02-19T16:06:07.983 回答