其他分享
首页 > 其他分享> > JSchException: Algorithm negotiation fail

JSchException: Algorithm negotiation fail

作者:互联网

背景

一个需求功能用到了SFTP文件上传的功能,使用的是之前封装好的工具类。

生产环境突然出现了问题,一直报错

com.jcraft.jsch.JSchException: Algorithm negotiation fail
        at com.jcraft.jsch.Session.receive_kexinit(Session.java:583) ~[jsch-0.1.51.jar:na]
        at com.jcraft.jsch.Session.connect(Session.java:320) ~[jsch-0.1.51.jar:na]

本地可以,测试环境也可以

排查

查看工具类代码,看到我们封装的SFTPUtils在获取连接的时候,使用的是JSCh这个jar

public ChannelSftp connect(String host, int port, String username, String password) {
        ChannelSftp sftp = null;
        try {
            JSch jsch = new JSch();
            jsch.getSession(username, host, port);
            sshSession = jsch.getSession(username, host, port);
            sshSession.setPassword(password);
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            LOG.info("SFTP Session connected.");
            Channel channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
            LOG.info("Connected to " + host);
        } catch (Exception e) {
            LOG.error(e.getMessage());
        }
        return sftp;
    }

在第11行 调用connect连接的时候,发生了报错

我这里的JSCh版本是0.1.49JDK版本是1.8

1. 排查主机用户名密码是否存在问题

我在本地使用Linux命令连接目标主机的SFTP(参考linux下FTP、SFTP命令详解)服务,上传下载都是正常的,所以排除了用户名和密码不正确的问题

2. 对比SSH版本是否存在差异

在测试环境使用ssh -V命令查看ssh版本信息

OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017

生产环境使用ssh -V

OpenSSH_8.4p1, OpenSSL 1.1.1l  24 Aug 2021

发现两个环境的SSH版本不一样,可能生产环境的SSH做了升级,两个版本的SSH协议存在某些差异,造成程序连接SFTP服务的时候出现了问题

3. 查找资料分析SSH通信过程,找出可能是哪一步的差异导致了BUG

上网查找资料,发现SSH通信分为5个阶段,参考SSH协议介绍

其中在第2个阶段中,双方根据本端和对端支持的算法,协商出最终使用的算法。问题可能出在这里。

7.4版本和8.4版本的OpenSSH默认的算法列表不同,导致了算法协商失败

4. 比较算法协议

查看当前OpenSSH版本支持通过ssh -p port -vvv ip查看支持的算法列表(参考What’s openssh default kexalgorithms?),重点查看关键字debug2: KEX algorithms:里面的值
在这里插入图片描述
上面的图片是输入 命令后的内容,重点关注红框的内容

测试环境结果:

debug2: KEX algorithms: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1

生产环境

debug2: KEX algorithms: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,ext-info-c

# ...

no matching key exchange method found. Their offer: diffie-hellman-group1-sha1,diffie-hellman-group14-sha1

发现生产环境OpenSSH默认的算法列表比测试环境要少了两个,并且在查看算法列表的时候,最后一行也提示了找不到匹配的秘钥交换方法diffie-hellman-group1-sha1,diffie-hellman-group14-sha1

查阅相关资料,原来ssh升级后,为了安全,默认不再采用原来一些加密算法。既然没有了原来的一些加密算法,那么就手工添加进去

解决

  1. 修改/etc/ssh/sshd_config文件:vim /etc/ssh/sshd_config
  2. 把缺少的算法协议加上:KexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group14-sha1
  3. 保存,重启sshd服务:service sshd restart
  4. 测试,问题解决

标签:negotiation,jsch,JSchException,sha1,hellman,算法,fail,diffie,sha256
来源: https://blog.csdn.net/w139074301/article/details/120579298