Java中JSch与jsch.addIdentity()完全详细解析
作者:qq_39927227
JSch是SSH2的一个纯Java实现,它允许你连接到一个sshd服务器,使用端口转发,X11转发,文件传输等等,这篇文章主要介绍了Java中JSch与jsch.addIdentity()完全详细解析,需要的朋友可以参考下
前言
JSch(Java Secure Channel)是 JCraft 提供的纯 Java 实现的 SSH2 协议库,核心用于 Java 程序实现 SSH 远程登录、远程命令执行、SFTP 文件传输等操作。addIdentity() 是 JSch 中配置 SSH 密钥认证的核心方法,用于替代传统的密码登录,提升认证安全性,以下是详细解析。
一、JSch 基础认知
1. 核心用途
- SSH 远程执行命令(如 Linux 服务器操作);
- SFTP/SCP 文件上传、下载;
- 端口转发(SSH 隧道);
- 支持密码认证、公钥 / 私钥认证(核心场景)。
2. 依赖引入(Maven/Gradle)
使用 JSch 需先引入依赖(最新稳定版为 0.1.55):
<!-- Maven -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
<!-- Gradle -->
implementation 'com.jcraft:jsch:0.1.55'二、jsch.addIdentity () 方法详解
1. 核心作用
addIdentity() 用于向 JSch 实例添加SSH 私钥,实现公钥认证(无需输入密码即可登录 SSH 服务器),替代不安全的密码认证方式。SSH 公钥认证原理:本地生成公钥 / 私钥对,公钥上传至服务器~/.ssh/authorized_keys,本地用私钥签名,服务器用公钥验签完成认证。
2. 常用重载方法
JSch 提供多个重载的addIdentity(),覆盖不同私钥存储形式(文件、字节数组),以下是最常用的 3 种:
| ||||||||
参数说明:
privateKeyPath:私钥文件路径(如/home/user/.ssh/id_rsa);passphrase:私钥的加密密码(若私钥未加密,传null);name:身份标识(自定义,如 "ssh-key-1");privateKey/publicKey:私钥 / 公钥的字节数组;
3. 基础使用示例(私钥文件认证)
场景 1:未加密的私钥文件
import com.jcraft.jsch.*;
import java.util.Properties;
public class JSchDemo {
public static void main(String[] args) {
JSch jsch = new JSch();
String host = "192.168.1.100"; // 远程服务器IP
String user = "root"; // 登录用户名
int port = 22; // SSH端口
try {
// 1. 添加私钥(无密码加密)
jsch.addIdentity("/home/user/.ssh/id_rsa"); // 本地私钥文件路径
// 2. 创建SSH会话
Session session = jsch.getSession(user, host, port);
// 跳过主机密钥验证(生产环境不建议,可配置known_hosts)
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
// 3. 连接会话(无需密码,通过私钥认证)
session.connect();
System.out.println("SSH连接成功:" + session.isConnected());
// 4. 后续操作(如执行命令、SFTP传输)...
// 5. 释放资源
session.disconnect();
} catch (JSchException e) {
e.printStackTrace();
}
}
}场景 2:加密的私钥文件
若私钥生成时设置了密码(如ssh-keygen -t rsa时输入了 passphrase),需传入解密密码:
// 替换addIdentity行,传入私钥路径+解密密码
jsch.addIdentity("/home/user/.ssh/id_rsa", "my-key-pass123");4. 进阶示例(字节数组形式的私钥)
适用于私钥存储在配置中心(如 Nacos、Apollo),以字符串 / 字节数组获取的场景:
public static void connectWithKeyBytes() throws JSchException {
JSch jsch = new JSch();
String host = "192.168.1.100";
String user = "root";
// 从配置中心读取的私钥字符串(需去除换行/空格,或保留原始格式)
String privateKeyStr = "-----BEGIN RSA PRIVATE KEY-----\n" +
"MIIEpAIBAAKCAQEAxX...(省略私钥内容)...\n" +
"-----END RSA PRIVATE KEY-----";
byte[] privateKey = privateKeyStr.getBytes();
String passphrase = "my-key-pass123"; // 私钥密码(无则传null)
// 添加字节数组形式的私钥
jsch.addIdentity("ssh-key-1", privateKey, null, passphrase.getBytes());
// 创建会话并连接(同基础示例)
Session session = jsch.getSession(user, host, 22);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
System.out.println("字节数组私钥认证成功");
session.disconnect();
}三、关键注意事项
1. 私钥格式要求
- JSch 支持OpenSSH 格式的私钥(如
id_rsa,PEM 格式),不支持 PKCS#8 格式(需转换); - 转换命令(PKCS#8→OpenSSH):
ssh-keygen -p -m PEM -f id_rsa;
2. 服务器端配置
- 公钥需上传至服务器
~/.ssh/authorized_keys(权限需为 600); - 服务器
sshd_config需开启公钥认证:PubkeyAuthentication yes; - 服务器
~/.ssh目录权限需为 700,否则会触发认证失败。
3. 生产环境最佳实践
- 禁止跳过主机密钥验证(
StrictHostKeyChecking=no):需将服务器公钥加入本地known_hosts文件; - 私钥加密存储:避免明文写在代码中,通过配置中心 / 环境变量获取;
- 资源释放:Session、Channel(SFTP/Exec)使用后必须
disconnect()/disconnect(),避免资源泄漏; - 异常处理:捕获
JSchException(如认证失败、连接超时、私钥错误),区分不同错误码(如AUTH_FAILED)。
4. 常见问题排查
异常现象 | 原因 | 解决方案 |
|---|---|---|
Auth fail | 私钥不匹配 / 权限错误 / 服务器公钥未配置 | 1. 核对私钥路径;2. 检查服务器 authorized_keys 权限;3. 验证私钥密码 |
invalid privatekey | 私钥格式错误(如 PKCS#8) | 转换为 OpenSSH 格式(PEM) |
Connection refused | 端口错误 / SSH 服务未启动 | 核对端口(默认 22);检查服务器 sshd 服务状态 |
四、扩展场景:结合 SFTP 使用
添加身份认证后,可快速实现 SFTP 文件传输:
// 连接成功后,创建SFTP通道
ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
// 上传文件
sftpChannel.put("/本地文件路径/test.txt", "/远程服务器路径/test.txt");
// 下载文件
sftpChannel.get("/远程服务器路径/test.txt", "/本地文件路径/test.txt");
// 关闭通道
sftpChannel.disconnect();
总结
到此这篇关于Java中JSch与jsch.addIdentity()完全详细解析的文章就介绍到这了,更多相关Java JSch与jsch.addIdentity()内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
