当系统与系统之间的通信需要大文件共享数据,并且是远程的关系,很多时候都会用到安全的文件传输协议SFTP。
到目前为止,碰到了两种关于SFTP的链接方式:
- 基于用户名密码的方式连接SFTP;
- 基于密匙的方式连接SFTP(可以无密码登陆);
两种的主要区别在于后者需要有SFTP服务器的密匙文件、以专网IP(SFTP服务端只允许报备过的IP访问)开放的形式获取文件,这样的安全性应该更高些。
以下是基于jsch的两种连接方式:
/** 用户名密码的方式连接SFTP * @param host * @param port * @param username * @param password * @return */ public ChannelSftp connect(String host, int port, String username, String password) throws JSchException{ ChannelSftp csftp = null; JSch jsch = new JSch(); Session sshSession = jsch.getSession(username, host, port); sshSession.setPassword(password); Properties sshConfig = new Properties(); sshConfig.put("StrictHostKeyChecking", "no"); sshSession.setConfig(sshConfig); sshSession.connect();//可设置超时时间 Channel channel = sshSession.openChannel("sftp"); channel.connect();//可设置超时时间 csftp = (ChannelSftp)channel; return csftp; } /** * 支持密钥的方式登陆 * @param ip * @param username * @param password 非必须 * @param port * @param privateKey 必须,由远程SFTP服务器生成提供并存放在客户端服务器上 * @param passphrase 非必须 */ public ChannelSftp connectWithKey(String ip, String username, String password, int port, String privateKey, String passphrase) throws Exception{ JSch jsch = new JSch(); if (privateKey != null && !"".equals(privateKey)) {//设置密钥和密码 if (passphrase != null && "".equals(passphrase)) {//设置带口令的密钥 jsch.addIdentity(privateKey, passphrase); } else { jsch.addIdentity(privateKey);//设置不带口令的密钥 } } Session session = null; if(port <=0){//连接服务器,采用默认端口 session = jsch.getSession(username, ip); }else{//采用指定的端口连接服务器 session = jsch.getSession(username, ip ,port); } if (session == null) {//如果服务器连接不上,则抛出异常 throw new Exception("session is null"); } if(StringUtils.isNotBlank(password))//密码不为空则设置密码 session.setPassword(password); Properties sshConfig = new Properties(); sshConfig.put("StrictHostKeyChecking", "no");//设置第一次登陆的时候提示,可选值:(ask | yes | no) session.setConfig(sshConfig); session.connect();//设置登陆超时时间 Channel channel = (Channel)session.openChannel("sftp");//创建sftp通信通道 channel.connect(); ChannelSftp sftp = (ChannelSftp)channel; return sftp; } /** * 密钥方式调用示例 * 其中"/usr/local/.ssh/xxx_remote_rsa"为SFTP服务器生成并提供给调用客户端服务器,并存放在客户端服务器上 * @return * @throws SftpException */ public void doVisit(){ try{ ChannelSftp sftp = ftp.connectWithKey(host, username, null, port, "/usr/local/.ssh/xxx_remote_rsa",null);//支持密钥的方式登陆 }catch(Exception e){ e.printStackTrace(); } }