JSchException: Algorithm negotiation fail异常处理过程
场景:应用详情的评论页,用户评论文字+图片将直接上传到我们的sftp服务器中。
异常产生:用户在模拟测试时发现上传图片后,图片找不到,查看后端erreo日志发现以下内容:
2020-10-22 23:52:03,207 [com.aspire.mo.module.comment.util.CommentUtil]- 社交评论图片上传到资源服务器失败
java.lang.Exception: java.lang.Exception: com.jcraft.jsch.JSchException: Algorithm negotiation fail
at com.aspire.mo.module.comment.util.Util.synActivityFile(Util.java:75)
at com.aspire.mo.module.comment.util.Util.uploadCateFileURL(Util.java:50)
at com.aspire.mo.module.comment.util.CommentUtil.uploadImageFile(CommentUtil.java:145)
at com.aspire.mo.module.comment.service.AddBaseCommentServlet.doPost(AddBaseCommentServlet.java:380)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.aspire.common.filter.xssfilter.XSSFilter.doFilter(XSSFilter.java:60)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:615)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:311)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:776)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:705)
at org.apache.jk.common.ChannelSocket$
Caused by: java.lang.Exception: com.jcraft.jsch.JSchException: Algorithm negotiation fail
at com.aspire.mo.framework.sftp.SFTPServer.login(SFTPServer.java:58)
at com.aspire.mo.framework.sftp.SFTPUtils.upload(SFTPUtils.java:45)
at com.aspire.mo.module.comment.util.Util.synActivityFile(Util.java:67)
... 24 more
Caused by: com.jcraft.jsch.JSchException: Algorithm negotiation fail
at com.jcraft.jsch.Session.receive_kexinit(Session.java:552)
at com.jcraft.jsch.Session.connect(Session.java:299)
at com.jcraft.jsch.Session.connect(Session.java:162)
at com.aspire.mo.framework.sftp.SFTPServer.initSession(SFTPServer.java:138)
at com.aspire.mo.framework.sftp.SFTPServer.login(SFTPServer.java:47)
... 26 more
解决过程:
1.检查配置文件中的sftp地址、用户名和密码是否错误:
经检查发现配置皆为正确的,且可以正常上传下载。
2.查看ssh版本是否相同,结果为大致相同:
[root@LGJF-ZYC5-MMSC-WEB18 ~]# ssh -V
OpenSSH_8.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
[root@LGJF-ZYC5-MMSC-LJCL01 ~]# ssh -V
OpenSSH_8.4p1, OpenSSL 1.0.1e-fips 11 Feb 2013
3.怀疑时JDK版本低导致,但由于生产环境不能直接升,所以继续查看报错日志,怀疑是代码中连接sftp服务器组件包jsch-0.1.48.jar版本低导致。然后去下载了一个新的包替换后,在下面测试中又出现以下异常:
https://repo1.maven.org/maven2/com/jcraft/jsch/0.1.55/jsch-0.1.55.jar
2020-10-23 00:21:29,307 [com.aspire.mo.module.comment.util.CommentUtil]- 社交评论图片上传到资源服务器失败
java.lang.Exception: java.lang.Exception: com.jcraft.jsch.JSchException: Session.connect: java.io.IOException: End of IO Stream Read
at com.aspire.mo.module.comment.util.Util.synActivityFile(Util.java:75)
at com.aspire.mo.module.comment.util.Util.uploadCateFileURL(Util.java:50)
at com.aspire.mo.module.comment.util.CommentUtil.uploadImageFile(CommentUtil.java:145)
at com.aspire.mo.module.comment.service.AddBaseCommentServlet.doPost(AddBaseCommentServlet.java:380)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.aspire.common.filter.xssfilter.XSSFilter.doFilter(XSSFilter.java:60)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:615)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:311)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:776)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:705)
at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.Exception: com.jcraft.jsch.JSchException: Session.connect: java.io.IOException: End of IO Stream Read
at com.aspire.mo.framework.sftp.SFTPServer.login(SFTPServer.java:58)
at com.aspire.mo.framework.sftp.SFTPUtils.upload(SFTPUtils.java:45)
at com.aspire.mo.module.comment.util.Util.synActivityFile(Util.java:67)
... 24 more
Caused by: com.jcraft.jsch.JSchException: Session.connect: java.io.IOException: End of IO Stream Read
at com.jcraft.jsch.Session.connect(Session.java:565)
at com.jcraft.jsch.Session.connect(Session.java:183)
at com.aspire.mo.framework.sftp.SFTPServer.initSession(SFTPServer.java:138)
at com.aspire.mo.framework.sftp.SFTPServer.login(SFTPServer.java:47)
... 26 more
4.经过搜索得知:是JDK 1.6版本低导致,因为JDK 1.6的加密算法和OPENSSH 8支撑的加密算法不一致。那么解决方法如下:
方案1:升级JDK到1.8版本,因为jdk 1.8支持了大多数的加密算法。
方案2:保持jdk 1.6版本,修改openssh配置文件
1.修改/etc/ssh/sshd_config配置文件,添加jdk 1.6支持的加密算法,如下:
KexAlgorithms +diffie-hellman-group1-sha1
注意:
-
如果使用的是jsch-0.1.52 jar包,只需按上述方法修改完就行;
-
如果使用的是jsch-0.1.53及以上jar包,还需要对代码做如下修改:
修改代码,在session中指定加密算法为:diffie-hellman-group1-sha1,如下所示:
Properties sshConfig = new Properties();
sshConfig.put("kex", "diffie-hellman-group1-sha1");
为什么要修改代码呢?因为建立连接时openssh会把它支持的所有加密算法发给jsch,让jsch从中间挑一个。如果列表中有
diffie-hellman-group1-sha1
算法,jsch-0.1.52则会优先选择该算法,这个算法恰好是jdk 1.6支持的,所以连接成功。而jsch-0.1.53及以后的jar包默认选择其他算法,该算法jdk 1.6并不支持,所以报错。如果要使用jsch-0.1.53及以后的jar包,就需要在代码中指定使用
diffie-hellman-group1-sha1
算法。
由于生产环境限制,我们使用的是jdch-0.1.52.jar,替换到生产后,并将sshd配置文件添加加密算法后重启,经验证,图片上传成功,问题解决!