1、SFTP信用公钥配置

1.1 客户端生成密钥对

以DSA举例: 

ssh-keygen –t dsa

执行该命令后,在home/用户名/.ssh目录下,会生成id_dsa和id_dsa.pub两个文件

1.2 将id_dsa.pub公钥文件上传至服务端的home/用户名/.ssh目录下

scp id_dsa.pub 用户名@服务端IP:/home/用户名/.ssh

此时还需要输入密码

1.3服务端添加信任公钥

登录服务端,进入到/home/用户名/.ssh目录,将刚刚拷贝的id_dsa.pub文件的内容加入到authorized_keys文件中

cat id_dsa.pub >> authorized_keys

1.4 服务端分别修改authorized_key文件和.ssh的权限为600和700

chmod 600 authorized_keys

chmod 700 .ssh

1.5 测试

在客户端执行:

sftp –oPort=端口 用户名@服务端IP

如果不需要输入密码就可以连上,则说明配置成功

 

2、基于JSCH库的sftp操作

Java代码  

1. public class SftpUtil {  
2.     private final static Logger          log       = LoggerFactory.getLogger(SftpUtil.class);  
3.   
4.     /** SFTP */  
5.     public static final String           SFTP      = "sftp";  
6.     /** 通道 */  
7.     private ChannelSftp                  channel;  
8.     /** session */  
9.     private Session                      session;  
10.   
11.     /** 规避多线程并发 */  
12.     private static ThreadLocal<SftpUtil> sftpLocal = new ThreadLocal<SftpUtil>();  
13.   
14.     /** 
15.      * 获取sftpchannel 
16.      *  
17.      * @param connectConfig 连接配置 
18.      * @return 
19.      * @throws Exception  
20.      * @throws JSchException 
21.      */  
22.     private void init(ConnectConfig connectConfig) throws Exception {  
23.         String host = connectConfig.getHost();  
24.         int port = connectConfig.getPort();  
25.   
26.         String userName = connectConfig.getUserName();  
27.   
28.         //创建JSch对象  
29.         JSch jsch = new JSch();  
30.   
31.         //添加私钥(信任登录方式)  
32.         if (StringUtils.isNotBlank(connectConfig.getPrivateKey())) {  
33.             jsch.addIdentity(connectConfig.getPrivateKey());  
34.         }  
35.   
36.         session = jsch.getSession(userName, host, port);  
37.         if (log.isInfoEnabled()) {  
38.             log.info(" JSCH Session created,sftpHost = {}, sftpUserName={}", host, userName);  
39.         }  
40.   
41.         //设置密码  
42.         if (StringUtils.isNotBlank(connectConfig.getPassWord())) {  
43.             session.setPassword(connectConfig.getPassWord());  
44.         }  
45.   
46.         Properties config = new Properties();  
47.         config.put("StrictHostKeyChecking", "no");  
48.         session.setConfig(config);  
49.         //设置超时  
50.         session.setTimeout(connectConfig.getTimeout());  
51.         //建立连接  
52.         session.connect();  
53.         if (log.isInfoEnabled()) {  
54.             log.info("JSCH Session connected.sftpHost = {}, sftpUserName={}", host, userName);  
55.         }  
56.   
57.         //打开SFTP通道  
58.         channel = (ChannelSftp) session.openChannel(SFTP);  
59.         //建立SFTP通道的连接  
60.         channel.connect();  
61.         if (log.isInfoEnabled()) {  
62.             log.info("Connected successfully to sftpHost = {}, sftpUserName={}", host, userName);  
63.         }  
64.     }  
65.   
66.     /** 
67.      * 是否已连接 
68.      *  
69.      * @return 
70.      */  
71.     private boolean isConnected() {  
72.         return null != channel && channel.isConnected();  
73.     }  
74.   
75.     /** 
76.      * 获取本地线程存储的sftp客户端 
77.      *  
78.      * @return 
79.      * @throws Exception  
80.      */  
81.     public static SftpUtil getSftpUtil(ConnectConfig connectConfig) throws Exception {  
82.         SftpUtil sftpUtil = sftpLocal.get();  
83.         if (null == sftpUtil || !sftpUtil.isConnected()) {  
84.             sftpLocal.set(new SftpUtil(connectConfig));  
85.         }  
86.         return sftpLocal.get();  
87.     }  
88.   
89.     /** 
90.      * 释放本地线程存储的sftp客户端 
91.      */  
92.     public static void release() {  
93.         if (null != sftpLocal.get()) {  
94.             sftpLocal.get().closeChannel();  
95.             sftpLocal.set(null);  
96.         }  
97.     }  
98.   
99.     /** 
100.      * 构造函数 
101.      * <p> 
102.      * 非线程安全,故权限为私有 
103.      * </p> 
104.      *  
105.      * @throws Exception  
106.      */  
107.     private SftpUtil(ConnectConfig connectConfig) throws Exception {  
108.         super();  
109.         init(connectConfig);  
110.     }  
111.   
112.     /** 
113.      * 关闭通道 
114.      *  
115.      * @throws Exception 
116.      */  
117.     public void closeChannel() {  
118.         if (null != channel) {  
119.             try {  
120.                 channel.disconnect();  
121.             } catch (Exception e) {  
122.                 log.error("关闭SFTP通道发生异常:", e);  
123.             }  
124.         }  
125.         if (null != session) {  
126.             try {  
127.                 session.disconnect();  
128.             } catch (Exception e) {  
129.                 log.error("SFTP关闭 session异常:", e);  
130.             }  
131.         }  
132.     }  
133.   
134.     /** 
135.      * 下载文件 
136.      *  
137.      * @param downDir 下载目录 
138.      * @param src 源文件 
139.      * @param dst 保存后的文件名称或目录 
140.      * @throws Exception 
141.      */  
142.     public void downFile(String downDir, String src, String dst) throws Exception {  
143.         channel.cd(downDir);  
144.         channel.get(src, dst);  
145.     }  
146.   
147.     /** 
148.      * 删除文件 
149.      *  
150.      * @param filePath 文件全路径 
151.      * @throws SftpException 
152.      */  
153.     public void deleteFile(String filePath) throws SftpException {  
154.         channel.rm(filePath);  
155.     }  
156.   
157.     @SuppressWarnings("unchecked")  
158.     public List<String> listFiles(String dir) throws SftpException {  
159.         Vector<LsEntry> files = channel.ls(dir);  
160.         if (null != files) {  
161.             List<String> fileNames = new ArrayList<String>();  
162.             Iterator<LsEntry> iter = files.iterator();  
163.             while (iter.hasNext()) {  
164.                 String fileName = iter.next().getFilename();  
165.                 if (StringUtils.equals(".", fileName) || StringUtils.equals("..", fileName)) {  
166.                     continue;  
167.                 }  
168.                 fileNames.add(fileName);  
169.             }  
170.             return fileNames;  
171.         }  
172.         return null;  
173.     }  
174. }

  

 说明:

2.1 ConnectConfig包含了建立sftp连接所需要的全部参数信息

Java代码  


1. //添加私钥(信任登录方式)  
2.         if (StringUtils.isNotBlank(connectConfig.getPrivateKey())) {  
3.             jsch.addIdentity(connectConfig.getPrivateKey());  
4.         }

Java代码  

1. /** 
2.      * 获取本地线程存储的sftp客户端 
3.      *  
4.      * @return 
5.      * @throws Exception  
6.      */  
7.     public static SftpUtil getSftpUtil(ConnectConfig connectConfig) throws Exception {  
8.         SftpUtil sftpUtil = sftpLocal.get();  
9.         if (null == sftpUtil || !sftpUtil.isConnected()) {  
10.             sftpLocal.set(new SftpUtil(connectConfig));  
11.         }  
12.         return sftpLocal.get();  
13.     }  
14.   
15.     /** 
16.      * 释放本地线程存储的sftp客户端 
17.      */  
18.     public static void release() {  
19.         if (null != sftpLocal.get()) {  
20.             sftpLocal.get().closeChannel();  
21.             sftpLocal.set(null);  
22.         }  
23.     }