当系统与系统之间的通信需要大文件共享数据,并且是远程的关系,很多时候都会用到安全的文件传输协议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();
}
}