Java访问SFTP服务器,踩了私钥的坑

背景

Java 程序访问第三方SFTP服务器下载文件,第三方只提供账号+私钥(key.ppk文件)

引入工具包(jsch)

建议引用最新版本,一开始版本过低,报错了



    com.jcraft
    jsch
    0.1.54

DEMO

package com.ctrip.ibu.yzy.test.ftp;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

import java.util.Properties;
import java.util.Vector;

public class FTPTest {
    public static void main(String[] args) {
        JSch jsch = new JSch();
        Session session = null;
        ChannelSftp channel = null;
        String path = FTPTest.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        try {
            jsch.addIdentity(path + "key.ppk");
            session = jsch.getSession("username", "host", 22);
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.setTimeout(20000);
            session.connect();
            channel = (ChannelSftp) session.openChannel("sftp");
            channel.connect();

            Vector vector = channel.ls("/infiles/");
            for (Object obj : vector) {
                if (obj instanceof ChannelSftp.LsEntry) {
                    ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) obj;
                    System.out.println(entry.getFilename());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            channel.quit();
            session.disconnect();
        }
    }
}

控制台输出infiles目录下所有 文件名

.
..
634_Hotel_report_20190521.csv.gz
634_Hotel_report_20190306.csv.gz
634_Hotel_report_20190412.csv.gz
634_POS_report_20190509.csv.gz
634_POS_report_20190512.csv.gz
634_Hotel_report_20190409.csv.gz

jsch 其他方法可以自行谷歌

踩坑

以上看起来没有什么问题,当我发布到测试环境(linux)的时候,运行报异常:

com.jcraft.jsch.JSchException: invalid privatekey: [B@392b0008

网上翻了好多帖子也没有找到解决方案,猜测是秘钥问题,果然看到有说mac系统无法使用ppk远程登录的帖子。

解决方案

下载Puttygen,将key.ppk 转换成 key.pem

image.png

修改后的代码,测试通过

boolean windows = System.getProperty("os.name").toLowerCase().contains("windows");
String path = getClass().getClassLoader().getResource(windows ? "key.ppk" : "key.pem").getPath();
......

你可能感兴趣的:(Java访问SFTP服务器,踩了私钥的坑)