Jsch连接openSSH高版本出现Algorithm negotiation fail
摘要:OpenSSH升级后,Java SFTP客户端因算法协商失败报错"Algorithm negotiation fail"。官方JSch库已停止维护,最新版本0.1.55虽可使用但存在安全隐患。测试发现OpenSSH 8+移除了旧算法导致兼容性问题。解决方案是切换到社区维护版jsch(0.2.15+),该版本兼容性好且支持新算法。建议逐步迁移至社区版,而非通过修改SSH配置
前言
最近做项目,升级了服务器的操作系统版本,openSSH被系统默认升级了,发现sftp客户端(Java)连接出现了失败,报错Algorithm negotiation fail,然后发现一系列的安全漏洞和官方版本在2018年后就不维护了,虽然0.1.55和0.1.54还能继续用,但是加密和加签算法不再迭代的隐患考虑,切换社区维护版是最终的解决办法。
准备demo
检查笔者以前的专门小主机的openssh版本:OpenSSH_8.9p1
并不是最新版,不过也可以复现问题,实际上openSSH8.2p1也可能有问题
随便写个demo
package com.feng.jsch.demo;
import com.jcraft.jsch.*;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;
public class JschDemo {
public static void main(String[] args) {
String host = "192.168.0.105";
int port = 22;
String username = "tom";
String password = "xxxxxx";
String localFile = "/Users/huahua/Fleet-1.48.261.dmg";
String remoteFile = "/home/sftp_users/tom/Fleet-1.48.261.dmg";
JSch jsch = new JSch();
Session session = null;
try {
// 创建 Session 并设置属性
session = jsch.getSession(username, host, port);
session.setPassword(password);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
// 建立连接
session.connect();
// 打开 SFTP 通道
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
// 上传文件
sftpChannel.put(Files.newInputStream(Paths.get(localFile)), remoteFile, ChannelSftp.OVERWRITE);
System.out.println("文件上传成功!");
sftpChannel.ls("/home/sftp_users/tom/").forEach(System.out::println);
sftpChannel.rm("/home/sftp_users/tom/Fleet-1.48.261.dmg");
sftpChannel.ls("/home/sftp_users/tom").forEach(System.out::println);
// 关闭连接
sftpChannel.exit();
session.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
0.1.50
在依赖0.1.50版本时
<dependencies> <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.50</version> </dependency> </dependencies>
提示有安全漏洞,忽略直接连吧
com.jcraft.jsch.JSchException: Algorithm negotiation fail
at com.jcraft.jsch.Session.receive_kexinit(Session.java:582)
at com.jcraft.jsch.Session.connect(Session.java:320)
at com.jcraft.jsch.Session.connect(Session.java:183)
at com.feng.jsch.demo.JschDemo.main(JschDemo.java:32)
就报错了,按照提示升级0.1.54
然后升级0.1.54吧,最新版本是0.1.55
实测上传成功
看看其中有什么变更吧,实际上现在能使用的就这2个版本了
官方网站已经打不开了,且Maven仓库说项目移交到开源社区维护了,最后的官方版本是2018年发布的
通过Maven信息,可以看到是jdk1.6打包的
笔者这里测试成功,但是OpenSSH因为安全漏洞问题会移除一些加密加签算法,而jsch不再更新。所以切换为社区版是唯一的解决办法,同理虽然官方版本还可以使用,但是每台服务器的openSSH版本和加密加签算法不可能完全一样,所以不一定适合其他操作系统和其他openSSH版本。有可能使用官方最新版本还是会出现算法缺少的报错。
看到网上说在ssh中加入已经移除的加密加签算法,但是这个安全性可能需要评估,毕竟ssh默认移除这些算法也是有理由的。
为了验证兼容情况,笔者升级OpenSSH版本为
实测官方版本0.1.55仍然可以访问,当然笔者测试有限,不排除出现不兼容的情况。
社区版
根据Maven提示,使用0.2.17(这个版本Maven使用最高),实际推荐是0.2.15或以上版本,以下版本有安全漏洞
<dependency>
<groupId>com.github.mwiede</groupId>
<artifactId>jsch</artifactId>
<version>0.2.17</version>
</dependency>
代码什么都不改即可,兼容性真好,因为加入了新算法,所以ssh连接时,速度会快一点,测试效果与官方版本一致
总结
目前ssh主要用于登录远程Linux服务器,同时文件可以在这个基础上传输,所以有sftp也是使用的ssh通道,后面发展出各种骚操作,比如通过ssh登录数据库,其实ssh就是提供通道,用于传输文件,数据库连接管理。ssh发展了很多代,在openSSH7的时候基本上都是兼容很多旧的算法,但是在openSSH8开始,移除了很多老的算法,所以如果客户端没更新算法库,很可能出现算法匹配不上的报错Algorithm negotiation fail。类似https,加密和加签算法是客户端和服务端协商,看看大家都认可那些算法,从共有的算法选出一个,所以国密ssl的网页,在chrome浏览器是访问不了的,因为客户端不支持国密ssl加密套件。
更多推荐
所有评论(0)