使用Java代码连接SFTP遇JSchException: Algorithm negotiation fail问题求助
这个问题我之前帮好几个开发者排查过,核心原因是可运行Jar包在打包时可能丢失了JSch依赖的算法配置文件,或者JVM在Jar运行模式下加载安全策略的方式有差异,导致JSch和SFTP服务器的算法协商失败。下面是一步步的解决办法:
解决步骤
1. 检查Jar包是否包含JSch的算法配置文件
JSch依赖jsch.jar里的META-INF/jsch.policy和算法相关的配置文件。如果你的可运行Jar是用Maven Shade或者其他插件打包的,很可能不小心把这些配置文件给覆盖或者漏掉了:
- 先解压你的可运行Jar,看看
META-INF目录下有没有jsch.policy文件,以及是否包含JSch的算法实现类。 - 如果用Maven打包,确保
maven-shade-plugin没有排除JSch的资源文件,添加资源合并规则:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/jsch.policy</resource> </transformer> <!-- 别忘了添加主类的Transformer --> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.your.package.YourMainClass</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
2. 显式指定JSch支持的算法
有时候JSch默认的算法集合和服务器不匹配,你可以在代码里手动指定兼容的算法集合,强制协商通过。在session.connect()之前添加以下代码:
// 指定密钥交换算法(KEX) session.setConfig("kex", "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1"); // 指定服务器主机密钥算法 session.setConfig("server_host_key", "ssh-rsa,ssh-dss"); // 指定加密算法(客户端到服务器/服务器到客户端) session.setConfig("cipher.s2c", "aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc"); session.setConfig("cipher.c2s", "aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc");
这些是通用的兼容算法,你也可以联系SFTP服务器管理员获取服务器支持的算法列表,再精准调整。
3. 检查JVM的安全策略设置
普通运行时你可能用的是IDE自带的JVM,而Jar运行时调用的是系统JVM,两者的java.security配置可能不同。比如有些JVM默认禁用了旧的加密算法(如3DES、SHA1),但SFTP服务器正好依赖这些算法:
- 找到JVM安装目录下的
jre/lib/security/java.security文件,检查jdk.tls.disabledAlgorithms或jdk.certpath.disabledAlgorithms配置,把需要的算法从禁用列表移除。 - 或者在运行Jar时通过JVM参数临时放宽安全限制(仅建议在信任的服务器环境使用):
java -Djdk.tls.disabledAlgorithms="" -jar your-sftp-app.jar
4. 升级JSch版本
旧版本的JSch可能存在算法兼容漏洞或缺失支持的算法,把依赖升级到最新稳定版(比如0.1.55及以上),很多协商问题在新版本里已经修复。Maven依赖配置如下:
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.55</version> </dependency>
5. 验证Jar包的类路径
确保你的可运行Jar包含了所有必要的依赖,除了JSch本身,还要检查是否有JSch依赖的其他类库。可以用以下命令查看类加载情况,确认JSch的类是否被正确加载:
java -jar your-app.jar -verbose
内容的提问来源于stack exchange,提问作者Ilavarapu Brahmaiah
相关产品推荐
相关产品推荐

