com.jcraft.jsch.JSchException: UnknownHostKey
Posted
技术标签:
【中文标题】com.jcraft.jsch.JSchException: UnknownHostKey【英文标题】: 【发布时间】:2011-01-01 11:37:25 【问题描述】:我正在尝试使用Jsch 在 Java 中建立 SSH 连接。我的代码产生以下异常:
: 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);
【问题讨论】:
另见How to resolve Java UnknownHostKey, while using JSch SFTP library? 【参考方案1】: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");
【讨论】:
【参考方案2】:我在 @Jairo Martínez
写的已删除答案之一中找到了解决方案首先,服务器需要将主机存储为散列 rsa
ssh-keyscan -H -t rsa SERVER_IP_ADDRESS >> known_hosts_file
另外,需要告诉Jsch主机密钥是hashed
session.setConfig("HashKnownHosts", "yes");
【讨论】:
【参考方案3】:虽然问题已得到普遍回答,但我发现自己有一个 case,即使现有的 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 设置,尽管他们似乎不太喜欢 eager 来修复他们的 bugs。
【讨论】:
我们的情况类似,ecdsa-sha2-nistp384
,您的解决方案运行良好。根据openssh-keyscan manual 和我们的需要,我们运行ssh-keyscan -t rsa,ecdsa example.org >> known_hosts
。
我遇到了这样的问题,但异常是 JSchException: reject HostKey: 而不是 JSchException: UnknownHostKey (这可能有助于其他一些用户)
我必须按照@krishnakumarp 的建议另外添加 setKnownHosts 文件【参考方案4】:
避免主机密钥检查存在安全风险。
JSch 使用 HostKeyRepository 接口及其默认实现 KnownHosts 类来管理它。您可以通过实现 HostKeyRepository 来提供允许特定密钥的替代实现。或者您可以将您想要允许的密钥保留在 known_hosts format 的文件中并调用
jsch.setKnownHosts(knownHostsFileName);
或者使用如下的公钥字符串。
String knownHostPublicKey = "mysite.com ecdsa-sha2-nistp256 AAAAE............/3vplY";
jsch.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));
查看Javadoc了解更多详情。
这将是一个更安全的解决方案。
Jsch 是开源的,你可以从here 下载源代码。在示例文件夹中,查找 KnownHosts.java 以了解更多详细信息。
【讨论】:
【参考方案5】:我在这个愚蠢的问题上浪费了很多时间,我认为这个消息是非常正确的“我正在访问的文件中没有主机”但是你的系统上可以有多个 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:\Users\my_local_user\.ssh 下的 Windows 主页中,我只是将它们合并并对齐以解决问题。
希望这对将来的某人有所帮助
【讨论】:
【参考方案6】:提供主机的公钥 rsa 密钥:-
String knownHostPublicKey = "mywebsite.com ssh-rsa AAAAB3NzaC1.....XL4Jpmp/";
session.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));
【讨论】:
在 jsch 版本 0.1.50 中对我不起作用(jsch 中总是有 NPE),但在最新版本 0.1.53 中它可以工作。 当 Jsch 代码 (Util.byte2str()) 需要 UTF-8 编码时,这个 (String.getBytes()) 是否会提供 unicode 编码字符的字节数组?【参考方案7】:你也可以这样做
session.setConfig("StrictHostKeyChecking", "no");
它不安全,而且它是一种不适合实时环境的解决方法,因为它会禁用全球已知的主机密钥检查。
【讨论】:
虽然此代码可能有助于回答问题,但仅代码的答案质量不高。更好的答案是解释代码的作用,告诉在哪里插入,解释为什么采用这种方法,并链接到相关文档。【参考方案8】:我会:
-
尝试从命令行输入
ssh
并接受公钥(主机将添加到~/.ssh/known_hosts
,然后从Jsch 一切都应该正常工作)-OR-
使用以下代码将 JSch 配置为不使用“StrictHostKeyChecking”(这会引入不安全性,仅应用于测试目的):
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
选项#1(将主机添加到~/.ssh/known_hosts
文件)是我的偏好。
【讨论】:
JSch#setConfig("StrictHostKeyChecking", "no")
会做同样的工作,但只需一行
旁注:当我无权修改源代码时,我使用此反馈配置我的~/.ssh/config
文件以修复上述错误
你对你的 .ssh/config 做了什么?我遇到了同样的错误。
这是不安全的,根据该原则,确实不应该被选为正确答案。 setKnownHosts() 和 setFingerPrint() 选项是在不忽略 ssh 进程的一个重要方面的情况下执行此操作的方法。编辑:根据我的经验,#1 在 Eclipse 等某些 IDE 环境中不起作用。
它在 Eclipse 中为我完成了这项工作......正是我在测试环境中所需要的......【参考方案9】:
设置已知主机优于设置指纹值。
当您设置已知主机时,尝试从应用程序运行的框中手动 ssh(第一次,在应用程序运行之前)。
【讨论】:
【参考方案10】:根据您用于 ssh 的程序,获取正确密钥的方法可能会有所不同。 Putty(在 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 替代方案。我发现 putty 处理 SSH 密钥的方式是将它们以非标准格式存储在注册表中,提取起来很麻烦。
【讨论】:
在cygwin
中使用h ssh 的windows 上(你必须下载openssl
包和依赖项)我已经能够下载~/.ssh/known_hosts
。感谢@CharityAbbott。【参考方案11】:
您还可以执行以下代码。它已经过测试并且可以正常工作。
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;
请替换适当的值。
【讨论】:
是的,我已将其添加以供参考。我会删除它。谢谢。 这在连接到某些提供键盘交互式身份验证方法的 SSH 服务器时产生了一些奇怪的身份验证问题。我多年来一直使用它来摆脱关键的东西,然后就在今天被某个服务器烧毁了。因为我没有通过 getPassword() 提供 PW,而是直接提供给 Session 对象。记住这一点。我不会再使用它了。【参考方案12】:有人能解决这个问题吗?我正在使用 Jscp 使用公钥 scp 文件 身份验证(我不想使用密码身份验证)。帮助将不胜感激!!!
这个***条目是关于主机密钥检查的,与公钥认证无关。
至于公钥认证,试试following sample 和你的普通(非加密)私钥,
【讨论】:
【参考方案13】:只需替换“user”、“pass”、“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);
【讨论】:
不适合我。同样,如果我注释掉config.put("StrictHostKeyChecking", "no");
,Eric Leschinski/Rakesh Acharya 的答案将失败。手动ssh -v
连接显示.ssh/known_hosts
文件确实包含密钥(ecdsa-sha2-nistp256
),但代码会这样做:com.jcraft.jsch.JSchException: UnknownHostKey: 131.132.x.x. RSA key fingerprint is c2:...
at com.jcraft.jsch.Session.checkHost(Session.java:805)
@ 987654328@
已经有一段时间了,我正在尝试使用 2013 年 6 月 13 日可用的 JSCH 库版本,因为从那时起库中的事情可能发生了变化以上是关于com.jcraft.jsch.JSchException: UnknownHostKey的主要内容,如果未能解决你的问题,请参考以下文章