使用jsch-0.1.51.jar的SFTP连接突发Algorithm negotiation fail错误求助
这种情况我维护老项目时碰到过——稳定跑了一年的SFTP突然报算法协商失败,十有八九是服务器端的SSH加密套件配置更新了,而你用的JSch 0.1.51是2014年的老版本,支持的加密算法和现在服务器要求的不匹配了。
问题根源
JSch 0.1.51默认只支持一些老旧的密钥交换(KEX)和加密算法,比如diffie-hellman-group1-sha1、3des-cbc这类。如果近期服务器为了安全,禁用了这些旧算法,换成了curve25519-sha256@libssh.org、aes256-gcm@openssh.com这类现代算法,老版本JSch就没法和服务器完成算法协商,直接抛出错误。
可行解决方案
1. 优先升级JSch版本(最优解)
这是最彻底的办法,把老的jsch-0.1.51.jar换成最新的稳定版(比如0.1.59,目前最新的稳定版本)。新版本JSch支持几乎所有主流的现代加密算法,不仅能解决协商问题,还能修复老版本存在的安全漏洞。
如果是Maven项目,直接更新依赖:
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.59</version> </dependency>
手动导包的话,替换成对应版本的jar文件即可。
2. 临时指定兼容的旧算法(应急方案)
如果暂时没法升级JSch,可以尝试手动指定服务器还未禁用的旧算法,在你的代码里添加如下配置(放在session.setConfig("StrictHostKeyChecking", "no");之后):
// 指定密钥交换算法 session.setConfig("kex", "diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1"); // 指定加密算法(服务器到客户端、客户端到服务器) session.setConfig("cipher.s2c", "aes128-cbc,3des-cbc,blowfish-cbc"); session.setConfig("cipher.c2s", "aes128-cbc,3des-cbc,blowfish-cbc");
⚠️ 注意:这个方案的前提是服务器还开启了这些旧算法,而且这类算法安全性较低,只能作为临时过渡用,长期还是建议升级JSch。
3. 检查服务器SSH配置(如果有权限)
如果能接触到服务器的sshd_config配置文件,可以查看KexAlgorithms、Ciphers、MACs这些项,确认是不是最近移除了JSch 0.1.51支持的算法。如果可以的话,临时加回这些算法应急,但同样不推荐长期保留,毕竟安全风险高。
结合你的代码示例
升级JSch版本后,代码可以简化为(不需要额外配置算法):
jsch.addIdentity(sftpIdentityFilePath); logger.info("*****************Getting SFTP Connection******************"); session = jsch.getSession(sftpUser, sftpHost, 2222); System.out.println("crossed session initialize"); session.setConfig("StrictHostKeyChecking", "no"); // 升级后无需额外算法配置,直接连接 session.connect(); // 后续获取SFTP通道逻辑...
内容的提问来源于stack exchange,提问作者DAWN




