Java linux SSH 免密(公钥)连接 并多服务器进行SCP

参考博客地址:

Java 实现 SCP 携带密码拷贝文件 - 龙凌云端 - 博客园

java免密连接SSH_寂寞的博客-CSDN博客

背景:项目中需要多台服务器之间进行文件传输,起初,使用的是密码认证的方式,但是服务器的密码会每三个月强制修改一次,这会影响到文件的正常传输,所以后面考虑使用ssh 公钥的认证方式

1、linux 不同服务器scp免密远程传输文件实例 ssh 免密登录 配置

本步骤参考本人博客:linux 不同服务器scp免密远程传输文件实例 ssh 免密登录_chen_lay的博客-CSDN博客

2、java 实现 ssh scp 免密(公钥)多服务器间的文件传输

a、maven依赖

<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-common -->
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-common</artifactId>
    <version>2.7.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-core -->
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-core</artifactId>
    <version>2.7.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-scp -->
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-scp</artifactId>
    <version>2.7.0</version>
</dependency>

b、具体的工具类

import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.keyverifier.DefaultKnownHostsServerKeyVerifier;
import org.apache.sshd.client.keyverifier.KnownHostsServerKeyVerifier;
import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.scp.client.ScpClient;
import org.apache.sshd.scp.client.ScpClientCreator;

import java.io.*;
import java.net.SocketAddress;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;

public class ScpClientUtil {
    private static String host = "10.186.83.100";
    private static String username = "username";
    private static String password = "password";
    private static Integer port = 22;

    private static String local = "/home/mg/data/customer_contract/";
    private static String remote = "/home/mg/data/customer_contract/";
    private static String idRsaPath = "/home/mg/.ssh/id_ras";

    public static void scpFile(String local, String remote, boolean strictHostKey) throws Exception {
        long startTime = System.currentTimeMillis();

        // 创建 SSH客户端
        SshClient client = SshClient.setUpDefaultClient();
        KnownHostsServerKeyVerifier verifier = new DefaultKnownHostsServerKeyVerifier(new ServerKeyVerifier() {
            @Override
            public boolean verifyServerKey(ClientSession clientSession, SocketAddress remoteAddress,
                                           PublicKey serverKey) {
                return !strictHostKey;
            }
        }, true);

        client.setServerKeyVerifier(verifier);
        // 启动 SSH客户端
        client.start();
        // 通过主机IP、端口和用户名,连接主机,获取Session
        ClientSession session = client.connect(username, host, port).verify().getSession();
        // 给Session添加密码
        // session.addPasswordIdentity(password);
        // publicKey方式认证
        session.addPublicKeyIdentity(getKeyPairFromString(readPemFile(new File(idRsaPath))));
        // 校验用户名和密码的有效性
        boolean isSuccess = session.auth().verify(10000L).isSuccess();

        // 认证成功
        if (isSuccess) {
            long middleTime = System.currentTimeMillis();
            System.out.println("Connect host cost time: " + (middleTime - startTime) / 1000.0 + "s.");

            ScpClientCreator creator = ScpClientCreator.instance();
            // 创建 SCP 客户端
            ScpClient scpClient = creator.createScpClient(session);

            System.out.println("Scp beginning.");
            // ScpClient.Option.Recursive:递归copy,可以将子文件夹和子文件遍历copy
            scpClient.upload(local, remote);
             scpClient.download(remote, local);
            System.out.println("Scp finished.");

            // 释放 SCP客户端
            if (scpClient != null) {
                scpClient = null;
            }

            // 关闭 Session
            if (session != null && session.isOpen()) {
                session.close();
            }

            // 关闭 SSH客户端
            if (client != null && client.isOpen()) {
                client.stop();
                client.close();
            }
        }

        long endTime = System.currentTimeMillis();
        System.out.println("Total Cost time: " + (endTime - startTime) / 1000.0 + "s.");
    }

    /**
     * 读取文件内容
     */
    public static String readPemFile(File f) throws IOException {
        try (InputStream is = Files.newInputStream(f.toPath());
             DataInputStream dis = new DataInputStream(is)) {
            byte[] bytes = new byte[(int) f.length()];
            dis.readFully(bytes);
            return new String(bytes);
        } catch (InvalidPathException e) {
            throw new IOException(e);
        }
    }

    /**
     * 获取密钥对
     */
    static KeyPair getKeyPairFromString(String pk) throws IOException, NoSuchAlgorithmException {
        final KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
        final KeyPair keyPair = rsa.generateKeyPair();
        final ByteArrayOutputStream stream = new ByteArrayOutputStream();
        stream.write(pk.getBytes());
        final ObjectOutputStream o = new ObjectOutputStream(stream);
        o.writeObject(keyPair);
        return keyPair;
    }

    public static void main(String[] args) throws Exception {
        scpFile(local, remote, false);
    }
}

c、执行结果:

Connect host cost time: 3.533s.
Scp beginning.
Scp finished.
Total Cost time: 4.545s.
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值