Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java com.jcraft.jsch.JSchException:UnknownHostKey_Java_Ssh_Jsch - Fatal编程技术网

Java com.jcraft.jsch.JSchException:UnknownHostKey

Java com.jcraft.jsch.JSchException:UnknownHostKey,java,ssh,jsch,Java,Ssh,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 我在Jsch文档中找不到如何验证主机密钥。我在下面包含了我的代码 import com.jcraft.jsch.JSch; import com.jcraft.jsch.Se

我试图用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
我在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);
        } 
    }
}
我想:

  • 从命令行尝试
    ssh
    ,并接受公钥(主机将被添加到
    ~/.ssh/known_hosts
    ,然后从Jsch一切都可以正常工作)-或-
  • 使用以下代码将JSch配置为不使用“StrictHostKeyChecking”(这会引入不安全性,应仅用于测试目的):

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

  • 选项#1(将主机添加到
    ~/.ssh/known_hosts
    文件)是我的首选选项。

    避免主机密钥检查存在安全风险

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

    或者使用公钥字符串,如下所示

    String knownHostPublicKey = "mysite.com ecdsa-sha2-nistp256 AAAAE............/3vplY";
    jsch.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));
    
    有关更多详细信息,请参阅

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


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

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

    jsch.setKnownHosts("C:\\Users\\cabbott\\known_hosts");
    
    假设我已将文件放置在Windows计算机上的
    C:\Users\cabbott
    中。如果您没有访问Linux机器的权限,请尝试

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

    有人能解决这个问题吗?我正在使用Jscp来使用公钥对scp文件进行加密 身份验证(我不想使用密码身份验证)。谢谢你的帮助

    此stackoverflow条目与主机密钥检查有关,与公钥身份验证无关


    至于公钥身份验证,请使用普通(非加密)私钥尝试,

    您还可以执行以下代码。它经过了测试,正在工作

    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;
            }
        }
    }
    

    请替换适当的值。

    设置已知主机比设置fingure打印值更好

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

    只需替换“用户”、“通过”、“SSHD\u IP”。并创建一个名为known_hosts.txt的文件,其中包含服务器的~/.ssh/known_hosts的内容。你会得到一个贝壳

    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);
        }
      }
    }
    
    你也可以简单地做

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

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

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

    String knownHostPublicKey = "mywebsite.com ssh-rsa AAAAB3NzaC1.....XL4Jpmp/";
    
    session.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));
    

    我在这个愚蠢的问题上浪费了很多时间,我认为信息是非常正确的“我正在访问的文件中没有主机”,但您的系统上可以有不止一个Known_主机文件(例如,我使用mobaXterm,它将自己的文件保存在安装目录中,从该根目录装入主目录)

    如果您遇到以下问题:它正在从命令行运行,但未形成应用程序尝试使用ssh访问远程服务器,并使用verbose-v选项检查当前使用的文件示例如下:

     ssh -v git@gitlab.com
     OpenSSH_6.2p2, OpenSSL 1.0.1g 7 Apr 2014
     debug1: Reading configuration data /etc/ssh_config
     debug1: Connecting to gitlab.com [104.210.2.228] port 22.
     debug1: Connection established.
     debug1: identity file /home/mobaxterm/.ssh/id_rsa type 1
     debug1: identity file /home/mobaxterm/.ssh/id_rsa-cert type -1
     debug1: identity file /home/mobaxterm/.ssh/id_dsa type -1
     debug1: identity file /home/mobaxterm/.ssh/id_dsa-cert type -1
     debug1: identity file /home/mobaxterm/.ssh/id_ecdsa type -1
     debug1: identity file /home/mobaxterm/.ssh/id_ecdsa-cert type -1
     debug1: Enabling compatibility mode for protocol 2.0
     debug1: Local version string SSH-2.0-OpenSSH_6.2
     debug1: Remote protocol version 2.0, remote software version OpenSSH_7.2p2      Ubuntu-4ubuntu2.1
     debug1: match: OpenSSH_7.2p2 Ubuntu-4ubuntu2.1 pat OpenSSH*
     debug1: SSH2_MSG_KEXINIT sent
     debug1: SSH2_MSG_KEXINIT received
     debug1: kex: server->client aes128-ctr hmac-sha1-etm@openssh.com zlib@openssh.com
     debug1: kex: client->server aes128-ctr hmac-sha1-etm@openssh.com zlib@openssh.com
     debug1: sending SSH2_MSG_KEX_ECDH_INIT
     debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
     debug1: Server host key: RSA b6:03:0e:39:97:9e:d0:e7:24:ce:a3:77:3e:01:42:09
     debug1: Host 'gitlab.com' is known and matches the RSA host key.
     debug1: Found key in /home/mobaxterm/.ssh/known_hosts:19
     debug1: ssh_rsa_verify: signature correct
    
    如您所见,该密钥位于:

    debug1: Found key in /home/mobaxterm/.ssh/known_hosts:19
    
    而不是在我的windows home中的C:\Users\my\u local\u user\.ssh下,我只是将它们合并并对齐以解决问题


    希望这对将来的人有所帮助

    虽然这个问题已经得到了普遍的回答,但我发现,即使是现有的已知主机条目也没有帮助。当SSH服务器发送ECDSA指纹时会发生这种情况,因此,您将有如下条目:

    |1|+HASH=|HASH= ecdsa-sha2-nistp256 FINGERPRINT=
    
    问题是JSch更喜欢SHA_RSA,连接时会尝试比较SHA-RSA指纹,这将导致关于“未知主机”的错误

    要解决此问题,只需运行:

    $ ssh-keyscan -H -t rsa example.org >> known_hosts
    

    或者向投诉更喜欢SHA_RSA而不是使用本地HostKeyAlgorithms设置,尽管他们似乎不太适合修复他们的设置。

    JSch\35; setConfig(“StrictHostKeyChecking”,“no”)
    也会做同样的工作,但仅在一行中注意:我使用此反馈来配置我的
    ~/.ssh/config
    文件,以修复当我无法修改源代码时出现的上述错误。您对.ssh/config做了什么?我也有同样的错误。这是不安全的,真的不应该被选为这个原则的正确答案。setKnownHosts()和setFingerPrint()选项是在不忽略ssh过程的一个重要方面的情况下实现这一点的方法。编辑:根据我的经验,#1在某些IDE环境(如Eclipse)中不起作用。它在Eclipse中为我完成了这项工作。。。这正是我在测试环境中所需要的……尝试关闭*nix主机上的sshd,并在前台启动一个线程:/usr/sbin/sshd-d这将从sshd方面为您提供大量调试信息。@AmmSokun每个人都能够解决此问题。请看答案。也请看是的,我添加了这一点以供参考。我会删除它。谢谢。当连接到某些提供键盘交互身份验证方法的SSH服务器时,这会产生一些奇怪的身份验证问题。我用它多年来摆脱了关键的东西,然后就在今天被某个服务器烧掉了。因为我没有通过getPassword()提供PW,而是直接提供给会话对象。记住这一点。我不会再使用它了。虽然这个代码可能有助于回答问题
    |1|+HASH=|HASH= ecdsa-sha2-nistp256 FINGERPRINT=
    
    $ ssh-keyscan -H -t rsa example.org >> known_hosts