使用libcurl实现SFTP公钥+密码双认证的配置问题
解决libcurl SFTP公钥+密码两步认证的配置问题
libcurl支持这种需要同时完成公钥认证和用户密码认证的场景,但你的当前实现存在两处关键错误,导致出现错误67(认证失败):
问题1:认证类型配置错误
你设置了CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_ANY,这会让libcurl自动选择单一的认证方式(比如成功完成公钥认证后就不再尝试密码,反之亦然),但服务器要求必须完成两步认证。你需要明确指定同时启用公钥和密码认证:
curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_PUBLICKEY | CURLSSH_AUTH_PASSWORD);
问题2:密码参数传递错误
你的代码中CURLOPT_PASSWORD的参数被错误地放在双引号中:
// 错误写法:传递的是字符串字面量"sUserPassword.Str()" curl_easy_setopt(curl, CURLOPT_PASSWORD, "sUserPassword.Str()");
这会导致libcurl使用错误的密码值,正确的写法应该直接传递变量值:
// 正确写法:传递实际的用户密码变量 curl_easy_setopt(curl, CURLOPT_PASSWORD, sUserPassword.Str());
修改后的完整核心配置代码
curl_easy_setopt(curl, CURLOPT_URL, myurl.Str); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &sftpfile); // 修改:指定同时启用公钥和密码认证 curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_PUBLICKEY | CURLSSH_AUTH_PASSWORD); curl_easy_setopt(curl, CURLOPT_USERNAME, sUser.Str()); // 修改:传递正确的密码变量 curl_easy_setopt(curl, CURLOPT_PASSWORD, sUserPassword.Str()); if (!sPrivateKeyFile.IsEmptyString()) { curl_easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, sPrivateKeyFile.Str()); } if (!sPublicKeyFile.IsEmptyString()) { curl_easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, sPublicKeyFile.Str()); } if (!sKnownHosts.IsEmptyString()) { curl_easy_setopt(curl, CURLOPT_SSH_KNOWNHOSTS, sKnownHostsFile.Str()); } if (!sPassword.IsEmptyString()) { curl_easy_setopt(curl, CURLOPT_KEYPASSWD, sPassword.Str()); } #ifdef _CURL_VERBOSE curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); #endif
额外注意事项
- 确认远程SSH服务器的配置确实要求
AuthenticationMethods publickey,password(先公钥后密码的两步认证),如果顺序相反,libcurl会自动适配服务器要求的认证顺序 CURLOPT_KEYPASSWD仅用于解密加密的私钥,若你的私钥未设置密码,可忽略该参数- 保持
CURLOPT_VERBOSE开启,能查看详细的SSH交互日志,帮助你确认libcurl是否按预期完成了两步认证流程
内容的提问来源于stack exchange,提问作者fborges22
相关产品推荐
相关产品推荐

