我试图使用 Jsch 建立一个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);
        } 
    }
}
有帮助吗?

解决方案

我会:

  1. 尝试 ssh 从命令行和接受公众的关键(主将加到 ~/.ssh/known_hosts 一切都应该然后工作的现从Jsch) -或者-
  2. 配置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.或者你可以把钥匙,你想要允许在一个文件在 会验证预格式 和呼叫

jsch.setKnownHosts(knownHostsFileName);

或一个公共钥匙串如下。

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

看看 如果是的话,为什么不试 更多的细节。

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

Jsch是开放源码你可以下载源 在这里,.在例子文件夹,寻找KnownHosts.java 要知道更多细节。

虽然有问题,一般得到答复,我发现我自己,有一个即使当现有的情况下 的known_hosts 的条目不帮助。这发生在一个SSH服务器发送ECDSA指纹,因此,你将有一个这样的条目:

|1|+HASH=|HASH= ecdsa-sha2-nistp256 FINGERPRINT=

的问题是,JSch的喜欢 SHA_RSA和在连接它会尝试比较SHA-RSA指纹,这将导致约“未知的主机”的错误。

要解决这个问题,只需运行:

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

或抱怨 Jcraft了解 prefering SHA_RSA,而不是使用本地 HostKeyAlgorithms 的设置,但他们似乎并不过于渴望以固定其错误的。

根据您使用什么程序SSH的方式来获得正确的密钥可能会有所不同。修补剂(流行的Windows)使用自己的格式为SSH密钥。有了,我已经看到Linux和BSD的最变种,你只需要在~/.ssh/known_hosts看。我通常是从一台Linux机器的ssh,然后将此文件复制到Windows机器。然后我使用类似的东西,以

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

假设我已经把我的Windows机器上C:\Users\cabbott文件。如果您没有访问到Linux机器,尝试 http://www.cygwin.com/

也许别人可以建议其他Windows替代品。我发现通过在注册表中它们存储在一个非标准格式的麻烦提取处理SSH密钥腻子的方式。

供应的主机的RSA公钥: -

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

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

您还可以执行下面的代码。它被测试和工作。

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

请替换适当的值。

您也可以简单地做

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

这不是安全的,这是一个解决方法并不适合实际环境中,因为它会禁用享誉全球的主机密钥检查。

只需替换 “用户”, “传球”, “SSHD_IP”。并创建一个名为known_hosts.txt与服务器的〜/ .ssh / known_hosts里面的内容文件。你会得到一个shell。

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

我损失了很多时间在这个愚蠢的问题,我认为该消息是完全正确“没有在文件中主机即时访问”,但你可以有比know_host文件更在你的系统上(为例我使用mobaXterm和它保持它自己的安装目录中安装从根家)内。

如果您遇到的:它的命令行工作,但没有形成应用程序试图访问您使用ssh远程服务器,并与该文件正在使用下面的例子详细-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

而不是在我家窗户下的C:\用户\ my_local_user \ SSH,我只是它们合并和解决问题对齐

希望这有助于有人在未来

  

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

此计算器条目是关于主机密钥检查,并没有相对于公钥认证。

作为用于公钥认证,尝试与以下样品你的普通(非加密的)私有密钥,

设置已知的主体比设定fingure打印值更好。

当设置公知的主体,尝试手动SSH(第一次,应用程序运行之前)从包装盒中的应用程序运行。

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");
}
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top