com.jcraft.jsch.JSchException:UnknownHostKey
我试图用Jschbuild立一个Java连接的SSH连接。 我的代码产生以下exception:
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
我无法find如何validationJsch文档中的主机密钥。 我在下面列出了我的代码。
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罚款) – 或 – -
configurationJSch不使用“StrictHostKeyChecking”(这引入了不安全感,应该仅用于testing目的),使用以下代码:
java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config);
选项#1(将主机添加到~/.ssh/known_hosts
文件)具有我的偏好。
避免主机密钥检查是安全风险。
JSch使用HostKeyRepository接口及其默认实现KnownHosts类来pipe理这个。 您可以通过实现HostKeyRepository来提供一个允许特定键的替代实现。 或者你可以保留你想要在文件中以known_hosts格式允许的密钥并进行调用
jsch.setKnownHosts(knownHostsFileName);
或者使用公钥string如下。
String knownHostPublicKey = "mysite.com ecdsa-sha2-nistp256 AAAAE............/3vplY"; jsch.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));
请参阅Javadoc了解更多详情。
这将是一个更安全的解决scheme。
Jsch是开源的,你可以从这里下载源代码。 在示例文件夹中,查找KnownHosts.java以了解更多详细信息。
根据您使用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/
也许别人可以build议另一个Windows的select。 我发现putty处理SSH密钥的方法是将它们以非标准格式存储在registry中,麻烦提取。
提供主机的公共rsa密钥:
String knownHostPublicKey = "mywebsite.com ssh-rsa AAAAB3NzaC1.....XL4Jpmp/"; session.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));
您也可以执行下面的代码。 它被testing和工作。
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; } } }
请replace适当的值。
你也可以简单的做
session.setConfig("StrictHostKeyChecking", "no");
这是不安全的,这是一个变通办法,不适合现场环境,因为它会禁用全局已知的主机密钥检查。
虽然这个问题已经得到了普遍的回答,但是我发现自己有一种情况 ,即使现有的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抱怨关于使用SHA_RSA而不是使用本地的HostKeyAlgorithms设置,尽pipe他们似乎不太愿意修复它们的错误 。
只需要replace“用户”,“通过”,“SSHD_IP”。 然后用服务器的〜/ .ssh / known_hosts的内容创build一个名为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); } } }
将该主机添加到〜/ .ssh / known_hosts。
有没有人能够解决这个问题? 我正在使用Jscp scp文件使用公钥authentication(我不想使用密码authentication)。 帮助将不胜感激!
这个stackoverflow条目是关于主机密钥检查,并且与公钥authentication没有关系。
至于公钥authentication,请使用普通(非encryption)私钥尝试下面的示例 ,
设置已知主机比设置打印值更好。
当您设置已知的主机时,尝试从应用程序运行的框中手动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"); } }
我在这个愚蠢的问题上浪费了很多时间,而且我认为这个消息是非常正确的“在我正在访问的文件中没有主机”,但是你的系统上可以有不止一个know_host文件(比如我使用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家庭在C:\ Users \ my_local_user \ .ssh,我只是合并他们和alignment解决问题。
希望这将有助于未来的人