JSchException: Algorithm negotiation fail問題解決之路

        最近一個需求用到了SFTP上傳功能,同事以前已經封裝好了SFTP工具類,用的是JSch,本着不要重複造輪子的想法,就直接拿來用了。交代下環境,JDK爲1.7,JSch版本爲0.1.51。自測經過、測試環境也OK,但上到生產環境卻拋出Algorithm negotiation fail異常,立即傻眼,下面是具體的異常信息:html

com.jcraft.jsch.JSchException: Algorithm negotiation fail
        at com.jcraft.jsch.Session.receive_kexinit(Session.java:583) ~[jsch-0.1.51.jar:na]
        at com.jcraft.jsch.Session.connect(Session.java:320) ~[jsch-0.1.51.jar:na]java

        更納悶的是,在本端(Client端)下用Linux命令SFTP(參考linux下FTP、SFTP命令詳解)鏈接對端(Server端)是成功的,也能上傳,首先排除了用戶名/密碼錯誤、網絡不通、未添加白名單之類的緣由了。而後想到是程序自己的問題,但爲何開發環境、測試環境都沒拋錯呢?難道是環境問題嗎?用ssh -V命令查看ssh版本,測試環境的本端和對端,以及生產環境的本端均是「OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010」,可是生產環境的對端倒是「OpenSSH_6.7p1, OpenSSL 1.0.1e-fips 11 Feb 2013」。看來真是環境問題了。linux

        冷靜下來,回到這個異常Algorithm negotiation fail,其意思是算法協商失敗。查看jsch源碼,異常發生在connect階段。上網查找資料(SSH協議介紹),發現SSH通信過程的五個階段中,有一個是密鑰和算法協商階段,在這個階段, 雙方根據本端和對端支持的算法,協商出最終使用的算法。問題就應該出在了這裏。5.3和6.7不一樣版本的OpenSSH默認的算法列表不一樣,致使了算法協商失敗。參考com.jcraft.jsch.JSchException: Algorithm negotiation fail算法

        那麼如何才能知道不一樣版本OpenSSH默認的算法列表呢?參考What's openssh default kexalgorithms?經過ssh -vvv serverIp命令,如以下圖所示:安全

 

        其中1和2標記的分別是5.3和6.7版本OpenSSH默認的KexAlgorithms,能夠看到,(本端)OpenSSH 5.​​​​3支持的diffie-hellman-group1-sha1 和 diffie-hellman-group-exchange-sha1 算法已經不在(對端)OpenSSH 6.7的默認列表裏面。服務器

        原來,ssh升級後,爲了安全,默認再也不採用原來一些加密算法。既然沒有了原來的一些加密算法,那麼就手工添加進去,參照這篇博文編輯/etc/sshd_config,加上 KexAlgorithms diffie-hellman-group1-sha1,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1網絡

重啓服務sshd。session

        就在覺得能搞定的時候,對端的同事(由於是我鏈接他們的SFTP服務器,所以上述添加修改工做是由他們來作的)說修改後重啓服務報錯了:ssh

        由於服務器不在我這邊,我不能親自調試,這下我也沒轍了。工具

        最後,不甘心天天要手動上傳,去JSch官網看一下,居然有所收穫,在它的ChangeLog裏發現,

Changes since version 0.1.52:
- bugfix: the rekey initiated by the remote may crash the session.

        是說修復了「由遠程發起的密鑰更新可能會使會話崩潰」的bug,這說的就是我遇到的問題啊,把JSch的版本升級到了最新的0.1.53,能夠成功上傳,問題解決。

相關文章
相關標籤/搜索