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配置文件添加加密算法后重啟,經驗證,圖片上傳成功,問題解決!