龙空技术网

SSHJ - 功能齐全的Java SSH库

每日开源代码 2090

前言:

眼前小伙伴们对“java访问sftp获取文件列表”大体比较关心,兄弟们都需要剖析一些“java访问sftp获取文件列表”的相关内容。那么小编也在网上收集了一些有关“java访问sftp获取文件列表””的相关资讯,希望兄弟们能喜欢,你们快快来学习一下吧!

SSH(Secure Shell,安全外壳协议),是专为远程登录会话和其他网络服务提供安全性的应用层协议。在日常开发中,包括登录远程服务器、远程执行命令脚本、文件传输等,都使用了 SSH 协议的实现。而 SSHJ 就是 SSH 协议的一个 Java 语言实现,其功能齐全,对 SSH 协议的特性实现全面,可以很方便地在代码中实现 SSH 相关功能应用,值得 Java 开发者了解使用。

SSH协议

简介

SSHJ 是 hierynomus 在 Github 上开源的 Java SSH 库,项目位于 ,目前版本为 v0.29.0。

SSHJ 功能齐全,支持从 known_hosts 文件读取验证公钥,支持公钥、密码和交互式的验证方式,支持命令、子系统和 Shell Channel,支持本地和远程端口转发,支持 SCP 安全拷贝协议,支持从版本 0 到 3 的完全的 SFTP 安全文件传输协议,支持广泛的加密、签名、压缩等的算法实现。

SSH协议和SSHJ库

安装

SSHJ 使用方便,可以使用 Maven 添加到项目依赖,在 pom.xml 中添加

<dependency>  <groupId>com.hierynomus</groupId>  <artifactId>sshj</artifactId>  <version>0.29.0</version></dependency>

SSHJ 的主要依赖是 SLF4J,另外,一些加密算法可能会需要 BouncyCastle,而 zlib 压缩则需要依赖 JZlib。

SSHJ 也可以自行编译,需要 Java6 及以上环境,并安装有 Unlimited strength Java Cryptography Extensions (JCE) 加密扩展包,运行命令

./gradlew clean build

SSH协议与SSHJ库

实例

SSHJ中的主要接口由 SSHClient 提供,其作为客户端用于连接 SSH 服务,每次连接都会生成一个会话 session,在一个 session 中进行具体操作。我们来看一个基本的使用例子:

package net.schmizz.sshj.examples;import net.schmizz.sshj.SSHClient;import net.schmizz.sshj.common.IOUtils;import net.schmizz.sshj.connection.channel.direct.Session;import net.schmizz.sshj.connection.channel.direct.Session.Command;import java.io.Console;import java.io.IOException;import java.util.concurrent.TimeUnit;/** 执行远程命令 */public class Exec {    private static final Console con = System.console();    public static void main(String... args)            throws IOException {        final SSHClient ssh = new SSHClient();        ssh.loadKnownHosts();        ssh.connect("localhost");        Session session = null;        try {            ssh.authPublickey(System.getProperty("user.name"));            session = ssh.startSession();            final Command cmd = session.exec("ping -c 1 toutiao.com");            con.writer().print(IOUtils.readFully(cmd.getInputStream()).toString());            cmd.join(5, TimeUnit.SECONDS);            con.writer().print("\n** exit status: " + cmd.getExitStatus());        } finally {            try {                if (session != null) {                    session.close();                }            } catch (IOException e) {                // 处理异常            }                        ssh.disconnect();        }    }}

这是使用 SSHJ 在远程服务器上执行命令的例子。首先创建一个 SSHClient,再加载 know_hosts,并连接到 localhost 所在的 SSH 服务。然后,使用本机用户名对应的公钥进行 SSH 登录验证,并启动会话。成功建立连接后,使用 session 的 exec 接口在 SSH 服务所在远程执行了一条 ping 命令,并从远程读取命令行输出,返回到本地命令行进行打印。最终,在完成任务后,关闭会话并断开连接。以此为基础可以实现远程命令的程序化实现,把需要手动登录 SSH 并执行命令的过程自动化。

SSHJ 实现了 SCP 安全拷贝协议,用于加密的文件在本地和远程之间拷贝复制。在 SSHClient 连接成功之后,使用 SCPFileTransfer 实现文件的上传和下载:

// SCP下载文件ssh.newSCPFileTransfer().download("test_file", new FileSystemFile("/tmp/"));// SCP上传文件ssh.newSCPFileTransfer().upload(new FileSystemFile(src), "/tmp/");

SSHJ 还实现了 SFTP 安全文件传输协议。与 SCP 相比,SFTP 可靠性高,可断点续传,支持更加广泛的远程文件操作。SSHJ 中使用 SFTPClient 来作为 SFTP 的客户端,在 SSHClient 连接成功后,创建 SFTPClient,并使用 put 和 get 进行上传和下载:

// SFTP下载final SFTPClient sftp = ssh.newSFTPClient();try {    s("test_file", new FileSystemFile("/tmp"));} finally {    s;}// SFTP上传final SFTPClient sftp = ssh.newSFTPClient();try {    s(new FileSystemFile(src), "/tmp");} finally {    s;}

利用 SSHJ,我们还就可以很方便地实现一个交互式 SSH 客户端,在本地命令行上实现对远程命令行的交互:

package net.schmizz.sshj.examples;import net.schmizz.sshj.SSHClient;import net.schmizz.sshj.common.StreamCopier;import net.schmizz.sshj.connection.channel.direct.Session;import net.schmizz.sshj.connection.channel.direct.Session.Shell;import net.schmizz.sshj.transport.verification.ConsoleKnownHostsVerifier;import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts;import java.io.File;import java.io.IOException;import net.schmizz.sshj.common.LoggerFactory;/** 交互式SSH客户端 */class RudimentaryPTY {    public static void main(String... args)            throws IOException {        final SSHClient ssh = new SSHClient();        final File khFile = new File(OpenSSHKnownHosts.detectSSHDir(), "known_hosts");        ssh.addHostKeyVerifier(new ConsoleKnownHostsVerifier(khFile, System.console()));        ssh.connect("localhost");        try {            ssh.authPublickey(System.getProperty("user.name"));            final Session session = ssh.startSession();            try {                session.allocateDefaultPTY();                final Shell shell = session.startShell();                new StreamCopier(shell.getInputStream(), System.out, LoggerFactory.DEFAULT)                        .bufSize(shell.getLocalMaxPacketSize())                        .spawn("stdout");                new StreamCopier(shell.getErrorStream(), System.err, LoggerFactory.DEFAULT)                        .bufSize(shell.getLocalMaxPacketSize())                        .spawn("stderr");                new StreamCopier(System.in, shell.getOutputStream(), LoggerFactory.DEFAULT)                        .bufSize(shell.getRemoteMaxPacketSize())                        .copy();            } finally {                session.close();            }        } finally {            ssh.disconnect();        }    }}

在这个例子中,使用了会话的 startShell 来启动一个命令行,而不像我们的第一个例子那样创建会话。在此之后,使用 SSHJ 提供的 StreamCopier,进行远程命令行输出流的获取,以及本地输入流的上传,从而完成了一个实时交互的 SSH 命令行。

SSH协议与SSHJ库

总结

SSHJ 作为一个使用 Java 语言实现的 SSH 库,其对于 SSH 协议的实现十分全面,包含的特性众多,在其所提供的 SSH 实现的比较中,SSHJ 对于协议和算法的实现覆盖程度很高,是实现 SSH 协议相关代码逻辑和应用的优秀选择。

SSHJ 项目代码质量高,历经数年的开发,项目一直处于活跃的开发和维护状态;项目代码量不大,代码结构设计较好,且提供了丰富的使用例子,值得有兴趣的开发者进行更进一步的学习研究和开源贡献。

标签: #java访问sftp获取文件列表 #sshjava