Libssh调用ssh_connect失败:ED25519签名无效求助
技术问询
我编写了一段使用Libssh初始化简单SSH客户端会话的代码,但调用ssh_connect时失败,代码如下:
int main() { ssh_session my_ssh_session; int rc; int port = 22; const char* password; int verbosity = SSH_LOG_FUNCTIONS; // Open session and set options my_ssh_session = ssh_new(); if (my_ssh_session == NULL) exit(-1); ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "10.10.10.100"); ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port); ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, "user"); ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); // Connect to server rc = ssh_connect(my_ssh_session); if (rc != SSH_OK) { fprintf(stderr, "Error connecting to localhost: %s\n", ssh_get_error(my_ssh_session)); ssh_free(my_ssh_session); exit(-99); }
我开启了高日志级别,发现问题可能与PKI签名相关,但我计划使用用户名密码认证,不知道如何解决。日志内容如下:
[2022/09/23 05:27:38.440674, 2] ssh_packet_newkeys: Received SSH_MSG_NEWKEYS [2022/09/23 05:27:38.440674, 4] ssh_pki_signature_verify: Going to verify a ssh-ed25519 type signature [2022/09/23 05:27:38.440674, 4] pki_verify_data_signature: ED25519 error: Signature invalid [2022/09/23 05:27:38.440674, 3] ssh_packet_socket_callback: Processing 276 bytes left in socket buffer [2022/09/23 05:27:38.440674, 3] ssh_packet_socket_callback: Packet: processed 0 bytes [2022/09/23 05:27:38.471928, 3] ssh_packet_socket_callback: Packet: processed 0 bytes [2022/09/23 05:27:38.471928, 3] ssh_connect: current state : 9
我可以通过Putty正常连接该SSH服务器,恳请各位提供帮助。
更新1
我查看了SSH日志,内容如下:
sshd[22105]: debug1: rekey in after 134217728 blocks [preauth] sshd[22105]: debug1: KEX done [preauth] sshd[22105]: debug1: Connection closed by 10.10.10.1 port 49917 [preauth]
看起来我的程序无法读取服务器主机密钥文件,或者不认可其格式。我尝试切换为RSA密钥,但问题依旧。我还在客户端运行ssh-keyscan验证服务器密钥,结果如下:
C:\Users\admin>ssh-keyscan 10.10.10.100 # 10.10.10.100:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 # 10.10.10.100:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 # 10.10.10.100:22 SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1 10.10.10.100 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHMq2kcCJ/hfdkxoDORhh9BfiLZ3IbGGyQ0xgBXYRgVi
更新2
我搭建了Dropbear SSH服务器,问题表现完全一致。
解决方案
核心问题
虽然你计划使用密码认证,但SSH连接建立的第一步是验证服务器主机密钥——Libssh客户端因无法通过该验证导致连接中断。Putty能正常连接是因为它会主动提示用户接受未知密钥,而Libssh默认采用严格验证逻辑。
具体解决步骤
手动指定信任的主机密钥(推荐)
将ssh-keyscan获取的服务器密钥直接配置到代码中,跳过系统已知主机文件读取:// 添加在ssh_connect调用之前 const char* trusted_host_key = "AAAAC3NzaC1lZDI1NTE5AAAAIHMq2kcCJ/hfdkxoDORhh9BfiLZ3IbGGyQ0xgBXYRgVi"; ssh_options_set(my_ssh_session, SSH_OPTIONS_HOSTKEY, trusted_host_key);临时禁用主机密钥验证(仅测试环境)
测试环境下可临时关闭验证(生产环境绝对禁止):ssh_options_set(my_ssh_session, SSH_OPTIONS_STRICTHOSTKEYCHECK, "no");升级Libssh或强制使用RSA密钥协商
部分旧版本Libssh对ED25519密钥支持存在bug,可升级到最新稳定版,或强制客户端使用RSA密钥:// 强制使用RSA密钥交换 ssh_options_set(my_ssh_session, SSH_OPTIONS_KEY_EXCHANGE, "diffie-hellman-group1-sha1"); ssh_options_set(my_ssh_session, SSH_OPTIONS_HOSTKEYS, "ssh-rsa");指定系统已知主机文件路径
若客户端系统存在known_hosts文件(如Windows下的C:\Users\admin\.ssh\known_hosts),可让Libssh读取该文件:ssh_options_set(my_ssh_session, SSH_OPTIONS_KNOWNHOSTS, "C:\\Users\\admin\\.ssh\\known_hosts");
补充说明
- 主机密钥验证是SSH协议的安全强制步骤,用于防范中间人攻击,生产环境务必保留验证逻辑。
- Dropbear服务器出现相同问题,说明问题根源不在服务器配置,而是Libssh客户端的主机密钥处理逻辑导致。
内容的提问来源于stack exchange,提问作者user3580480
相关产品推荐
相关产品推荐

