首页 > 其他分享 >记录JSch连接SFTP Exception:Algorithm negotiation fail问题解决

记录JSch连接SFTP Exception:Algorithm negotiation fail问题解决

时间:2024-08-12 10:29:55浏览次数:16  
标签:JSch negotiation Exception jsch 算法 session ssh 版本 SSH

问题描述:关于正式环境访问外网连接不成功


 1、首先检查是否开放防火墙(已确认开放),策略开放后,通过命令连接是否畅通:

 通过telnet命令,可以得出,访问畅通。

telnet 192.168.1.1 22

 2、查看生产环境日志,观察生产环境访问外网服务器异常:

抛出异常,提示:算法协商失败

com.jcraft.jsch.JSchException: Algorithm negotiation fail

  


 3、查找生产代码,本地通过代码模拟连接sftp,还原问题,

通过查看生产环境,jar引入为jsch-0.1.54

代码示例:

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

import java.io.FileOutputStream;
import java.io.OutputStream;

public class SFTPDownloadExample {

    public static void main(String[] args) {
        String host = "192.168.1.1";
        int port = 22;
        String user = "admin";
        String password = "root";
        String remoteFile = "/PEP/ac.ZIP";
        String localFile = "ac.ZIP";

        JSch jsch = new JSch();
        Session session = null;
        ChannelSftp channelSftp = null;

        try {
            // Connect to the server
            session = jsch.getSession(user, host, port);
            session.setPassword(password);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();

            // Open an SFTP channel
            Channel channel = session.openChannel("sftp");
            channel.connect();
            channelSftp = (ChannelSftp) channel;

            // Download the file
            try (OutputStream outputStream = new FileOutputStream(localFile)) {
                channelSftp.get(remoteFile, outputStream);
            }

            System.out.println("File downloaded successfully!");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (channelSftp != null && channelSftp.isConnected()) {
                channelSftp.disconnect();
            }
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
    }

}

使用测试类,执行此示例代码,模拟生产环境请求。

 本地重现问题,可以确认访问是没有问题的,可能出现在jar包或ssh版本上。

sftp和ssh使用的是同一加密算法,算法协商失败,意思就是客服端和服务端支持的算法不一致,然后就出现这个提示,因此需要检查一下支持的算法。


 4、查看SSH版本

ssh -V

 生产环境使用的版本为5.3

可以使用以下命令查看 Linux 服务器 SSH 默认支持的算法:

ssh -Q cipher
ssh -Q mac
ssh -Q kex
ssh -Q key

这些命令会列出支持的加密算法、消息认证码 (MAC) 算法、密钥交换算法和公钥算法。

如果 ssh -Q 命令不可用,你可以查看 SSH 配置文件 /etc/ssh/sshd_config 来了解支持的算法。你也可以使用 ssh -vv 进行调试,这将显示 SSH 客户端在连接时使用的详细信息,包括支持的算法。例如:

ssh -vv user@hostname

在输出中,你会看到有关加密算法、MAC 和密钥交换算法的信息。

默认情况下,SSH通常支持以下几种算法:
1. 加密算法:AES (Advanced Encryption Standard) 和 3DES (Triple Data Encryption Standard)。 2. 散列算法:SHA-2 (如SHA-256、SHA-512)。 3. 密钥交换算法:Diffie-Hellman (DH) 和 Elliptic Curve Diffie-Hellman (ECDH)。
这些算法可以根据具体的SSH实现和版本有所不同。 

我们当前使用的 jsch-0.1.54.jar 包,此版本大概为2016年9月3日

在这个版本中,JSCH 支持的默认算法主要包括:
加密算法:
对称加密算法:aes128-cbc, aes192-cbc, aes256-cbc, blowfish-cbc, 3des-cbc

消息认证码 (MAC) 算法:
hmac-md5, hmac-sha1

密钥交换算法:
diffie-hellman-group1-sha1

公钥算法:
ssh-rsa, ssh-dss
这些算法在较新的版本中可能会有所变化或增加新的选项

解决方案:

1、将jsch版本升级到新一点的版本

2、服务器向下兼容低版本算法

3、降低SSH版本,让对应的客户端可以直接连上,卸载当前ssh,安装别的版本


 1、将jsch版本升级到新一点的版本

  获取新的jar包,替换掉当前版本的jar包,重新启动服务,测试是否可以访问。

2、服务器向下兼容低版本算法

  修改ssh的配置文件

/etc/ssh/sshd_config

  在配置文件后新增

KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 

对应的算法必须包含客户端需要支持的算法,配置完成后重启ssh服务

要重启 SSH 服务,可以使用以下命令,具体命令可能取决于你使用的 Linux 发行版:

对于基于 systemd 的系统(如 Ubuntu 16.04 及以后版本、CentOS 7 及以后版本):
sudo systemctl restart sshd

对于基于 SysVinit 的系统(如较旧的 Debian 版本):
sudo service ssh restart

  • service sshd restart:通常用于基于 SysVinit 的系统。
  • systemctl restart sshd.service:用于基于 systemd 的系统。

 

其他问题导致:

JDK版本1.7以下,对应支持的算法较少,需要单独在JDK中进行配置

标签:JSch,negotiation,Exception,jsch,算法,session,ssh,版本,SSH
From: https://www.cnblogs.com/zcy99/p/18354443

相关文章