Boa*_*rdy 17 c++ ssh public-key libssh2 private-key
我正在开发一个项目,我正在使用C++中的libssh2将端口转发到MySQL.我已经使用它进行用户名/密码验证,但我现在想要使用公钥/私钥验证.libssh2的文档很差,所以我很难解决我需要做的事情.
我想要做的是让一个Android应用程序将数据发布到我的C++应用程序,其中C++将获得SSH详细信息以及auth密钥,并创建SSH隧道.C++正在获得关键,然后我正在执行以下操作来进行公钥认证.
else if (this->getAuthMethod() == SupportedAuthMethods::AUTH_PUBLICKEY)
{
string test = this->getSSHPrivateKey();
boost::replace_all(test, "\n", "");
unsigned char * key = (unsigned char *)test.c_str();
size_t sizeofkey = strlen((char*)key);
cout << key << endl;
stringstream logstream;
logstream << "Using public key authentication for SSH Host: " << this->getSSHHostnameOrIPAddress();
this->bitsLibrary->writeToLog(logstream.str(), "SSHTunnelForwarder", "authenticateSSHServer");
if (chosenAuthMethod & SupportedAuthMethods::AUTH_PUBLICKEY)
{
//int result = 0;
int result = libssh2_userauth_publickey(this->session, this->getUsername().c_str(), key, sizeofkey, SSHTunnelForwarder::publicKeyAuthComplete, 0);
if (result != 0)
{
char * error = NULL;
int len = 0;
int errbuf = 0;
libssh2_session_last_error(this->session, &error, &len, errbuf);
this->bitsLibrary->writeToLog(std::string(error), "SSHTunnelForwarder", "auth");
JSONResponseGenerator jsonResponse;
jsonResponse.generateJSONResponse(API_AUTH_FAILURE, "InvalidPublicKey");
return jsonResponse.getJSONString();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我在某个地方读到它不应该有新行,这就是为什么我要替换\n为空白字符但是有或没有它它没有什么区别.
最基本的文档提到其中一个参数libssh2_userauth_publickey是回调,如下所示:
int name(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract);
但我找不到任何关于这个回调是什么或它应该包含什么的信息.在我的函数调用libssh2_userauth_publickey我传入SSHTunnelForwarder::publicKeyAuthComplete,目前这个函数只有以下内容:
int SSHTunnelForwarder::publicKeyAuthComplete(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
const unsigned char *data, size_t data_len, void **abstract)
{
cout << "In SSH Auth Callback" << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的这个方法没有被调用,虽然我期望这甚至不是正确的.
当我运行上面的代码时,libssh2_userauth_publickey的结果为19,并且从get_last_message()方法返回的错误是invalid public key.我知道公钥文件很好,因为我可以在Android上的SSH应用程序中使用它,并且可以使用我的服务器成功进行身份验证.
更新1
我已经设法取得了一些进展,我发现有一个函数叫:
libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, const char *username, size_t username_len, const char *publickeyfiledata, size_t publickeyfiledata_len, const char *privatekeyfiledata, size_t privatekeyfiledata_len, const char *passphrase);
Run Code Online (Sandbox Code Playgroud)
我的libssh2版本来自NuGet包管理器,发现其中的最新版本实际上已经很老了,所以我在Visual Studio中从GitHub构建了最新的1.7.0版本,并将我的项目重新链接到这个新版本.
我现在已经用这个版本替换了原来的publickey auth函数,所以我的代码现在看起来像这样:
int result = libssh2_userauth_publickey_frommemory(this->session, username.c_str(), username.length(), nullptr, 0, test.c_str(), sizeofkey, nullptr);
Run Code Online (Sandbox Code Playgroud)
这个函数让我有点困惑,它想要公钥和私钥,因为我所知道的关于SSH的一切(公认的不是很大)公钥留在服务器上,想要登录的用户只能访问私有键.
我发现其他人问这个并且已经完成了一个补丁以允许公钥的空指针,所以我已经为公钥传递了nullptr,为公钥长度传递了0.我还为证书密码短语设置了一个nullptr,因为尚未设置.
当我现在运行此代码时,我现在得到错误-18 invalid username/public key combination.但是,我知道我使用的用户名和私钥文件是正确的,因为我可以在Android上的SSH客户端应用程序中使用它来连接到我的SSH服务器.
我找到了解决方案.我在更新1中所做的是实际的修复,但我的服务器密钥由于某种原因而不知道为什么会发生变化,所以当它说它无法将用户名与密钥链接时它是正确的.
完整的修复方法如下:
不要使用NuGet的libssh2它的旧版本.我从https://github.com/libssh2/libssh2/releases下载了GitHub的最新源代码,然后完成了在Visual Studio中构建libssh2的后续步骤.
以上步骤取自https://www.libssh2.org/mail/libssh2-devel-archive-2012-09/0029.shtml
libssh2在编译期间链接到openssl.
将您的项目链接到您刚为libssh2完成的最新构建并使用该方法
libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, const char *username, size_t username_len, const char *publickeyfiledata, size_t publickeyfiledata_len, const char *privatekeyfiledata, size_t privatekeyfiledata_len, const char *passphrase);
Run Code Online (Sandbox Code Playgroud)
就是这样.
| 归档时间: |
|
| 查看次数: |
1661 次 |
| 最近记录: |