You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JSch实现无密码SSH时遭遇Auth Cancel异常求助

解决JSch无密码SSH连接时的Auth Cancel异常

我之前也碰到过一模一样的JSch Auth Cancel问题,不管私钥带不带密码短语都报错,折腾了好一阵才理清原因,给你梳理几个关键排查方向和解决办法:

一、先排查SSH服务器端配置问题

很多时候这类异常不是代码的锅,而是服务器的SSH配置限制:

  • 检查服务器的sshd_config文件,确保PubkeyAuthentication设置为yes,如果修改了记得重启sshd服务(比如systemctl restart sshd)。
  • 确认服务器上的公钥存放路径正确,一般是~/.ssh/authorized_keys,而且权限必须严格:
    • ~/.ssh目录权限设为700(chmod 700 ~/.ssh)
    • authorized_keys文件权限设为600(chmod 600 ~/.ssh/authorized_keys)
      权限不对的话,服务器会直接拒绝公钥认证,触发Auth Cancel。

二、检查JSch代码的细节

代码里的小疏漏也会导致这个问题:

  • 确认addIdentity的私钥路径绝对正确,并且程序对该文件有读权限。如果是带密码短语的私钥,要确保密码参数传递正确,比如:
    jschConnector.addIdentity("/home/youruser/.ssh/id_rsa", "your_passphrase_here");
    
  • 先手动用ssh命令测试连接:ssh -i path_to_private_key yourusername@yourhost,如果手动连不上,那先解决服务器或密钥的问题;如果手动能连,再回头查代码。
  • 开启JSch的日志,看认证过程的详细输出,能帮你定位到底是哪一步失败:
    JSch.setLogger(new Logger() {
        @Override
        public boolean isEnabled(int level) {
            return true;
        }
        @Override
        public void log(int level, String message) {
            System.out.println("[JSch Log] " + message);
        }
    });
    
    日志里会显示比如“Authentications that can continue: publickey”或者“Server refused our key”这类关键信息。

三、排查密钥格式兼容性

JSch对新的OpenSSH私钥格式支持不太好:

  • 如果你的私钥开头是-----BEGIN OPENSSH PRIVATE KEY-----,可以转换成旧的PEM格式,用这个命令:
    ssh-keygen -p -m PEM -f path_to_private_key
    
    转换后私钥开头会变成-----BEGIN RSA PRIVATE KEY-----,JSch就能正常识别了。
  • 确认公钥已经完整添加到服务器的authorized_keys里,没有多余的空格、换行或者格式错误。

修正后的示例代码

给你一个能正常工作的参考代码:

JSch jschConnector = new JSch();
// 带密码短语的话加上第二个参数,不带就留空或者只传路径
jschConnector.addIdentity("/home/youruser/.ssh/id_rsa", "your_passphrase");

Session session = jschConnector.getSession("yourusername", "yourhost", 22);
// 生产环境建议配置known_hosts,这里临时跳过主机密钥检查
session.setConfig("StrictHostKeyChecking", "no");
session.connect();

// 示例:执行一个命令
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand("ls -l /home");
channel.connect();

// 读取命令输出
InputStream in = channel.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
    System.out.println(line);
}

channel.disconnect();
session.disconnect();

内容的提问来源于stack exchange,提问作者Madeeha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:26:22