本文主要是介绍Jsch版本升级引发的血案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
背景
我们项目需要通过SFTP对接大量上下游获取数据,但是由于某一个上游需要更换AWS Transfer Family
作为他们的SFTP服务,他们的SFTP服务使用更高版本的OpenSSH服务,原有的一些密钥算法已经不再支持,我们目前使用的Jcraft公司发布的Jsch版本已经没办法满足,需要进行升级。但是Jcraft公司的Jsch0.1.55
版本从2018年开始就停止维护,我们不得不升级到另一个mwiede
继续维护的Jsch版本(基于原有0.1.55
fork的分支)以满足更多算法的需要。
当前使用的JDK版本: 1.8.0_152-b16
升级前:
<dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.55</version>
</dependency>
升级后:
<dependency><groupId>com.github.mwiede</groupId><artifactId>jsch</artifactId><version>0.2.16</version>
</dependency>
升级Jsch版本后,该上游的AWS Transfer Family
SFTP服务能成功连接,但是我们其他上下游的陆陆续续连接失败,分别报以下几种类型的错误:
- com.jcraft.jsch.JSchProxyException: ProxySOCKS5: stream is closed"
- com.jcraft.jsch.JSchException: Session.connect: java.security.InvalidAlgorithmParameterException: DH key size must be multiple of 64, and can only range from 512 to 2048 (inclusive). The specific key size 3047 is not supported.
- com.jcraft.jsch.JSchAlgoNegoFailException: Algorithm negotiation fail: algorithmName=“server_host_key” jschProposal=“ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256” serverProposal=“ssh-rsa,ssh-dss”
解决方案
经排查,以上问题主要原因如下:
- com.jcraft.jsch.JSchAlgoNegoFailException: Algorithm negotiation fail: algorithmName=“server_host_key” jschProposal=“ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256” serverProposal=“ssh-rsa,ssh-dss” -
RSA/SHA1
签名算法在新版本Jsch中由于安全原因已经被默认关闭,由于有些上下游仍然使用旧版本的OpenSSH服务,因为没办法新版Jsch没办法连接,从以上报错信息可以看到,对方服务器需要ssh-rsa,ssh-dss
,因此我们需要在创建连接前对SFTP Session
额外添加以下配置:
session.setConfig("server_host_key", session.getConfig("server_host_key") + ",ssh-rsa");
session.setConfig("PubkeyAcceptedAlgorithms", session.getConfig("PubkeyAcceptedAlgorithms") + ",ssh-rsa,rsa-sha2-256")
- com.jcraft.jsch.JSchProxyException: ProxySOCKS5: stream is closed" - 同上,由于我们代理服务器也是使用的是旧版OpenSSH,因此加入上面配置即可。
- com.jcraft.jsch.JSchException: Session.connect: java.security.InvalidAlgorithmParameterException: DH key size must be multiple of 64, and can only range from 1024 to 2048 (inclusive). The specific key size 3047 is not supported. - 这是由于当前JDK版本不支持更高位数的Diffie-Hellman密钥交换算法的密钥长度,这里我们可以通过以下参数指定推荐的密钥长度
session.setConfig("dhgex_min", "1024")
session.setConfig("dhgex_max", "2048")
session.setConfig("dhgex_preferred", "2048")
完整代码如下:
// 设置JSchJSch jsch = new JSch();Session session = jsch.getSession(user, host, PORT);session.setPassword(passwd);// 设置配置信息java.util.Properties config = new java.util.Properties();config.put("StrictHostKeyChecking", "no");session.setConfig(config);session.setConfig("server_host_key", session.getConfig("server_host_key") + ",ssh-rsa");session.setConfig("PubkeyAcceptedAlgorithms", session.getConfig("PubkeyAcceptedAlgorithms") + ",ssh-rsa,rsa-sha2-256");session.setConfig("dhgex_min", "1024");session.setConfig("dhgex_max", "2048");session.setConfig("dhgex_preferred", "2048");// 连接到服务器session.connect();
这篇关于Jsch版本升级引发的血案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!