Java com.jcraft.jsch.JSchException: UnknownHostKey

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2003419/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 02:21:37  来源:igfitidea点击:

com.jcraft.jsch.JSchException: UnknownHostKey

javasshjsch

提问by Alex

I'm trying to use Jschto establish an SSH connection in Java. My code produces the following exception:

我正在尝试使用Jsch在 Java 中建立 SSH 连接。我的代码产生以下异常:

com.jcraft.jsch.JSchException: UnknownHostKey: mywebsite.com. 
RSA key fingerprint is 22:fb:ee:fe:18:cd:aa:9a:9c:78:89:9f:b4:78:75:b4

I cannot find how to verify the host key in the Jsch documentation. I have included my code below.

我在 Jsch 文档中找不到如何验证主机密钥。我在下面包含了我的代码。

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class ssh {
    public static void main(String[] arg) {

        try {
            JSch jsch = new JSch();

            //create SSH connection
            String host = "mywebsite.com";
            String user = "username";
            String password = "123456";

            Session session = jsch.getSession(user, host, 22);
            session.setPassword(password);
            session.connect();

        } catch(Exception e) {
            System.out.println(e);
        } 
    }
}

采纳答案by Pascal Thivent

I would either:

我要么:

  1. Try to sshfrom the command line and accept the public key (the host will be added to ~/.ssh/known_hostsand everything should then work fine from Jsch) -OR-
  2. Configure JSch to not use "StrictHostKeyChecking" (this introduces insecurities and should only be used for testing purposes), using the following code:

    java.util.Properties config = new java.util.Properties(); 
    config.put("StrictHostKeyChecking", "no");
    session.setConfig(config);
    
  1. 尝试ssh从命令行并接受公钥(主机将被添加到~/.ssh/known_hosts,然后一切都应该在 Jsch 中正常工作)-或-
  2. 使用以下代码将 JSch 配置为不使用“StrictHostKeyChecking”(这会引入不安全性,应仅用于测试目的):

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

Option #1 (adding the host to the ~/.ssh/known_hostsfile) has my preference.

选项#1(将主机添加到~/.ssh/known_hosts文件)有我的偏好。

回答by krishnakumarp

It is a security risk to avoid host key checking.

避免主机密钥检查是一种安全风险。

JSch uses HostKeyRepository interface and its default implementation KnownHosts class to manage this. You can provide an alternate implementation that allows specific keys by implementing HostKeyRepository. Or you could keep the keys that you want to allow in a file in the known_hosts formatand call

JSch 使用 HostKeyRepository 接口及其默认实现 KnownHosts 类来管理它。您可以通过实现 HostKeyRepository 来提供允许特定密钥的替代实现。或者,您可以将要允许的密钥保留在known_hosts 格式的文件中并调用

jsch.setKnownHosts(knownHostsFileName);

Or with a public key String as below.

或者使用如下的公钥字符串。

String knownHostPublicKey = "mysite.com ecdsa-sha2-nistp256 AAAAE............/3vplY";
jsch.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));

see Javadocfor more details.

有关更多详细信息,请参阅Javadoc

This would be a more secure solution.

这将是一个更安全的解决方案。

Jsch is open source and you can download the source from here. In the examples folder, look for KnownHosts.java to know more details.

Jsch 是开源的,您可以从这里下载源代码。在examples 文件夹中,查找KnownHosts.java 以了解更多详细信息。

回答by Charity Leschinski

Depending on what program you use for ssh, the way to get the proper key could vary. Putty (popular with Windows) uses their own format for ssh keys. With most variants of Linux and BSD that I've seen, you just have to look in ~/.ssh/known_hosts. I usually ssh from a Linux machine and then copy this file to a Windows machine. Then I use something similar to

根据您用于 ssh 的程序,获取正确密钥的方式可能会有所不同。Putty(在 Windows 中很流行)使用它们自己的 ssh 密钥格式。对于我见过的大多数 Linux 和 BSD 变体,您只需要查看~/.ssh/known_hosts. 我通常从 Linux 机器 ssh,然后将此文件复制到 Windows 机器。然后我使用类似的东西

jsch.setKnownHosts("C:\Users\cabbott\known_hosts");

Assuming I have placed the file in C:\Users\cabbotton my Windows machine. If you don't have access to a Linux machine, try http://www.cygwin.com/

假设我已将文件C:\Users\cabbott放在我的 Windows 机器上。如果您无法访问 Linux 机器,请尝试http://www.cygwin.com/

Maybe someone else can suggest another Windows alternative. I find putty's way of handling SSH keys by storing them in the registry in a non-standard format bothersome to extract.

也许其他人可以建议另一种 Windows 替代方案。我发现 putty 处理 SSH 密钥的方法是将它们以非标准格式存储在注册表中,提取起来很麻烦。

回答by ymnk

Has anyone been able to solve this problem? I am using Jscp to scp files using public key authentication (i dont want to use password authentication). Help will be appreciated!!!

有没有人能够解决这个问题?我正在使用 Jscp 到使用公钥认证的 scp 文件(我不想使用密码认证)。帮助将不胜感激!!!

This stackoverflow entry is about the host-key checking, and there is no relation to the public key authentication.

这个stackoverflow条目是关于主机密钥检查的,和公钥认证没有关系。

As for the public key authentication, try the following samplewith your plain(non ciphered) private key,

至于公钥认证,请使用您的普通(非加密)私钥尝试以下示例

回答by Vishnu Prasad Kallummel

You can also execute the following code. It is tested and working.

您还可以执行以下代码。它已经过测试和工作。

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UIKeyboardInteractive;
import com.jcraft.jsch.UserInfo;

public class SFTPTest {

    public static void main(String[] args) {
        JSch jsch = new JSch();
        Session session = null;
        try {
            session = jsch.getSession("username", "mywebsite.com", 22); //default port is 22
            UserInfo ui = new MyUserInfo();
            session.setUserInfo(ui);
            session.setPassword("123456".getBytes());
            session.connect();
            Channel channel = session.openChannel("sftp");
            channel.connect();
            System.out.println("Connected");
        } catch (JSchException e) {
            e.printStackTrace(System.out);
        } catch (Exception e){
            e.printStackTrace(System.out);
        } finally{
            session.disconnect();
            System.out.println("Disconnected");
        }
    }

    public static class MyUserInfo implements UserInfo, UIKeyboardInteractive {

        @Override
        public String getPassphrase() {
            return null;
        }
        @Override
        public String getPassword() {
            return null;
        }
        @Override
        public boolean promptPassphrase(String arg0) {
            return false;
        }
        @Override
        public boolean promptPassword(String arg0) {
            return false;
        }
        @Override
        public boolean promptYesNo(String arg0) {
            return false;
        }
        @Override
        public void showMessage(String arg0) {
        }
        @Override
        public String[] promptKeyboardInteractive(String arg0, String arg1,
                String arg2, String[] arg3, boolean[] arg4) {
            return null;
        }
    }
}

Please substitute the appropriate values.

请替换适当的值。

回答by sreenath V

setting known host is better than setting fingure print value.

设置已知主机比设置指纹打印值更好。

When you set known host, try to manually ssh (very first time, before application runs) from the box the application runs.

当您设置已知主机时,尝试从应用程序运行的框中手动 ssh(第一次,在应用程序运行之前)。

回答by dalvarezmartinez1

Just substitute "user", "pass", "SSHD_IP". And create a file called known_hosts.txt with the content of the server's ~/.ssh/known_hosts. You will get a shell.

只需替换“用户”、“通行证”、“SSHD_IP”。并使用服务器的 ~/.ssh/known_hosts 的内容创建一个名为 known_hosts.txt 的文件。你会得到一个壳。

public class Known_Hosts {
public static void main(String[] arg) {
    try {
        JSch jsch = new JSch();
        jsch.setKnownHosts("known_hosts.txt");
        Session session = jsch.getSession("user", "SSHD_IP", 22);
        session.setPassword("pass");
        session.connect();
        Channel channel = session.openChannel("shell");
        channel.setInputStream(System.in);
        channel.setOutputStream(System.out);
        channel.connect();
    } catch (Exception e) {
        System.out.println(e);
    }
  }
}

回答by Rakesh Acharya

JSch jsch = new JSch();
Session session = null;
try {
session = jsch.getSession("user", "hostname", 22); // default
UserInfo ui = new MyUserInfo();
session.setUserInfo(ui);
session.setPassword("password".getBytes());
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
System.out.println("Connected");
} catch (JSchException e) {
e.printStackTrace(System.out);
} catch (Exception e) {
e.printStackTrace(System.out);
} finally {
session.disconnect();
System.out.println("Disconnected");
}
}

回答by Amaury D

You can also simply do

你也可以简单地做

session.setConfig("StrictHostKeyChecking", "no");

It's not secure and it's a workaround not suitable for live environment as it will disable globally known host keys checking.

它不安全,它是一种不适合实时环境的解决方法,因为它会禁用全球已知的主机密钥检查。

回答by Mark Beer

Supply the public rsa key of the host :-

提供主机的公共 rsa 密钥:-

String knownHostPublicKey = "mywebsite.com ssh-rsa AAAAB3NzaC1.....XL4Jpmp/";

session.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));