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.49
,JDK
版本是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
升级后,为了安全,默认不再采用原来一些加密算法。既然没有了原来的一些加密算法,那么就手工添加进去
解决
- 修改/etc/ssh/sshd_config文件:
vim /etc/ssh/sshd_config
- 把缺少的算法协议加上:
KexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group14-sha1
- 保存,重启sshd服务:
service sshd restart
- 测试,问题解决
标签:negotiation,jsch,JSchException,sha1,hellman,算法,fail,diffie,sha256 来源: https://blog.csdn.net/w139074301/article/details/120579298