JSch(Java Secure Channel)是Jcraft维护的在Java项目用于连接SFTP服务器实现文件传输一个广为使用的Java Jar包。可惜的是该项目于2018年终止更新,最新版本停留在2018年11月发布的版本0.1.55。与此同时,很多SFTP服务器随着RFC4253标准的不断进化随之更新,由此导致客户端和服务器端版本不一致所带来的问题。
JSch作为RFC4253标准的存JAVA实现,代码相对精简,整个库只有276K。本文主要关注连接初始化部分,这里也是问题常发地带。SFTP基于SSH协议,所以只需要看一下SSH连接细节:
SSH连接基本步骤
建立TCP连接,客户端向服务器发出连接请求
服务器认证,双方互发自身身份认证信息,包括SSH版本号
加密协商,双方商定要使用的对称加密算法,使用诸如:"Diffie-Hellman” 密钥交换算法生成对称加密算法共享密钥。
认证,商定使用的认证方式,例如密钥或者密码,客户端服务器发出认证请求
然后是生成信道,会话,通信结束后销毁信道。
JSch代码实现
SSH连接的实现集中在Session的Connect方法,下图是最简单的用法之一,从实例化JSch全局入口类单例中获取session并调用它的connect方法会激活SSH连接的初始化流程:
下图为该方法的代码实现,可以清楚的看到SSH连接的实现逻辑:
具体可能遇到的问题
"Connection reset by peer"
这是TCP连接过程中遇到的问题,如果是一直发生,通常是由于网络防火墙阻塞了对远程服务器的访问。如果是间歇性的问题,要考虑网络的稳定性及防火墙的其他方面的设置。
“java.io.IOException: End of IO Stream Read”
如下图如示,在看到该JAVA异常栈之前,会在JSch的日志中观察到"SSH_MSG_KEXINIT"信号收不到回应,这通常是由于客户端和服务器版本兼容性造成的问题,客户端发出的密钥初始化请求得不到回应,比如服务器已经升级到最新RFC4253标准实现,而客户端还使用2018年或者以前的版本。解决办法升级客户端版本。
"Connection failed: Auth fail"
这种情况通常是由于客户端提供的认证信息不正确,但是有一种特殊情况需要引起注意。比如,如果服务器只允许 “publickey,keyboard-interactive”这两种认证方式,客户端通过用户名密码认证时会出现这种问题。解决办法,检查服务器的认证方式,选择可行的认证方法。如下图如示,Jsch客户端信息的打印方式会容易引起误解,实际上这种情况下,服务器端并不支持password这种认证方式。
本文暂时没有评论,来添加一个吧(●'◡'●)