使用 JSch 从 Java 连接到 SSH 服务器时出现“JSchException:拒绝 HostKey”

Posted

技术标签:

【中文标题】使用 JSch 从 Java 连接到 SSH 服务器时出现“JSchException:拒绝 HostKey”【英文标题】:"JSchException: reject HostKey" when connecting to SSH server from Java using JSch 【发布时间】:2020-04-23 11:19:54 【问题描述】:

我尝试根据说明在我的 Java 程序中使用 SSH 在 PythonAnywhere 中建立与 mysql 基础的连接:https://help.pythonanywhere.com/pages/AccessingMySQLFromOutsidePythonAnywhere

不幸的是,我每次都收到这个错误,而且我的想法已经用完了:

com.jcraft.jsch.JSchException: 拒绝 HostKey: ssh.pythonanywhere.com

public static void main(String[] args) 
    Tunnel tunnel = new Tunnel();
    try 
        tunnel.go();
     catch (Exception e) 
        e.printStackTrace();
    


public void go() throws Exception 
    String host = "ssh.pythonanywhere.com";
    String user = "username";
    String password = "password";
    int port = 22;

    int tunnelLocalPort = 9080;
    String tunnelRemoteHost = "username.mysql.pythonanywhere-services.com";
    int tunnelRemotePort = 3306;

    JSch jsch= new JSch();
    Session session = jsch.getSession(user,host,port);
    localUserInfo lui = new localUserInfo();
    session.setPassword(password);
    session.setUserInfo(lui);
    session.connect();
    session.setPortForwardingL(tunnelLocalPort,tunnelRemoteHost,tunnelRemotePort);
    System.out.println("Connecting");


class localUserInfo implements UserInfo 
    String passwd;

    @Override
    public String getPassphrase() return null; 

    @Override
    public String getPassword()  return null; 

    @Override
    public boolean promptPassword(String s)  return false; 

    @Override
    public boolean promptPassphrase(String s)  return false; 

    @Override
    public boolean promptYesNo(String s)  return false; 

    @Override
    public void showMessage(String s) 

我使用 PuTTY 成功连接,但无法让我的程序运行。

【问题讨论】:

【参考方案1】:

好的,

好像加了:

java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no");
session.setConfig(config);

帮助解决了异常。

【讨论】:

这不是正确的方法。通过设置StrictHostKeyChecking=no,您将失去对MITM attacks 的保护【参考方案2】:

JSch 无法验证 SSH 服务器主机密钥。

您的主机密钥存储库包含不同的主机密钥。

或者 JSch 尝试通过调用 UserInfo.promptYesNo 来提示用户手动验证主机密钥。当您的实现返回 false 时,主机密钥被拒绝。


有关验证主机密钥的正确方法,请参阅:How to resolve Java UnknownHostKey, while using JSch SFTP library?


请注意,即使在 PuTTY 中,您也必须在第一次连接时验证主机密钥。

【讨论】:

【参考方案3】:

启动您的应用程序一次

sftp.strictHostKeyChecking=no

这将在known_hosts中添加密钥,之后您可以将其切换回yes

【讨论】:

【参考方案4】:

FWIW,在我的情况下,使用 jsch 以编程方式 ssh 到另一台机器,即使我使用的是用户名/密码凭据,我也必须通过手动 ssh 用户名/pw 登录添加两个密钥(类型 ecdsa-sha2 -nistp256),以及在使用基于 rsa 密钥的登录时添加的一个(类型 ssh-rsa)。

【讨论】:

以上是关于使用 JSch 从 Java 连接到 SSH 服务器时出现“JSchException:拒绝 HostKey”的主要内容,如果未能解决你的问题,请参考以下文章

Jsch使用SSH协议连接到远程Shell执行脚本

Java通过ssh向服务器上传下载删除文件和操作Linux

在 Java 中通过 SSH 隧道连接到 Mongo 数据库

基于 JSch 实现服务的自定义监控解决方案

Java利用JSch实现sftp通过ssh上传下载删除文件及配置代码

JSch