Java JSchException:UnknownHostKey
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19063115/
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
JSchException: UnknownHostKey
提问by Atul Singh Yadav
I'm trying to use Jsch to establish an SSH connection in Java. I have set "StrictHostKeyChecking" to yes. I understand that the hostkey of the server has to be obtained before hand and store in the hostkey file before the first attempt to connect to the server. How can I get the HostKey of the server. My code produces the following exception:
我正在尝试使用 Jsch 在 Java 中建立 SSH 连接。我已将“StrictHostKeyChecking”设置为是。我知道在第一次尝试连接到服务器之前,必须事先获取服务器的主机密钥并将其存储在主机密钥文件中。如何获取服务器的 HostKey。我的代码产生以下异常:
com.jcraft.jsch.JSchException: UnknownHostKey: ASY-PC RSA key fingerprint is 22:fb:ee:fe:18:cd:aa:9a:9c:78:89:9f:b4:78:75:b4
com.jcraft.jsch.JSchException: UnknownHostKey: ASY-PC RSA 密钥指纹为 22:fb:ee:fe:18:cd:aa:9a:9c:78:89:9f:b4:78:75:b4
How can I make connection with StrictHostKeyChecking Yes. Here is my code.
如何与 StrictHostKeyChecking 建立连接 是。这是我的代码。
package sshexample;
import com.jcraft.jsch.*;
import java.io.*;
public class SSHexample
{
public static void main(String[] args)
{
String user = "user";
String password = "password";
String host = "192.168.100.103";
int port=22;
try
{
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "yes");
System.out.println("Establishing Connection...");
session.connect();
System.out.println("Connection established.");
System.out.println("Crating SFTP Channel.");
ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
}catch(Exception e) {
e.printStackTrace();
}
}
回答by Mubashar
You have to supply a KnownHostKeys file by calling following function
您必须通过调用以下函数来提供KnownHostKeys 文件
jsch.setKnownHosts(new FileInputStream(knownHostsFile));
jsch.setKnownHosts(new FileInputStream(knownHostsFile));
this file should have all the the known hosts' fingerprints separated by new lines.
这个文件应该有所有已知主机的指纹,用新行分隔。
for example
例如
hostname,10.1.1.120, ssh-rsa AAAAC3NzaC1yc2EAAAADAQABAAABAQCi5b647581SwC0uUDQw1ENjKSz3rhJMRRZEgIjHylvF4fbuAEzj645YoAf9SItb51MhetFAJrq98jYsHpedSm3IoMG+aR/P1CjsBz1RtJKlfR2NfYDCZ7Dyx11P8FnJbwbYif/GeG0xEujekwF1pyL0tNPmf0H4/GPR4mwrv/llGlB3Lo3BzxrGtl4f4X/oSHDoo7FrQkDwqOfeSM++3vPPHxyVO5zhFJ5u9f7M/uuxUeHS+YS5JWAI7NLXKgbiM9dluGzZU/6Awo3ux4x5ojL+kf29JEVxK+o6GfW2bIW+LhgIGZNThnN5nHzBVfNNHvQ7KC5ic0h2z2gbVpwJr1h
you can obtain this key from server by using any sftp client however following command may help if you are using linux or unix
您可以使用任何 sftp 客户端从服务器获取此密钥,但是如果您使用的是 linux 或 unix,以下命令可能会有所帮助
ssh-keyscan -t rsa 10.1.1.120
回答by nothing to know
After a few minutes of testing i found a solution for this. If you don't want to use the default knownHost
File, just create your own
经过几分钟的测试,我找到了解决方案。如果您不想使用默认knownHost
文件,只需创建自己的
This how the file could look:
这是文件的外观:
192.168.0.1 ssh-rsa
AAAAC3NzaC1yc2EAAAADAQABAAABAQCi5b647581SwC0uUDQw1ENjKSz3rhJMRRZEgIjHylvF4fbuAEzj645YoAf9SI
tb51MhetFAJrq98jYsHpedSm3IoMG+aR/P1CjsBz1RtJKlfR2NfYDCZ7Dyx11P8FnJbwbYif
/GeG0xEujekwF1pyL0tNPmf0H4/GPR4mwrv/llGlB3Lo3BzxrGtl4f4X
/oSHDoo7FrQkDwqOfeSM++3vPPHxyVO5zhFJ5u9f7M/uuxUeHS+YS5JWAI7NLXKgbiM9dluGzZU
/6Awo3ux4x5ojL+kf29JEVxK+o6GfW2bIW+LhgIGZNThnN5nHzBVfNNHvQ7KC5ic0h2z2gbVpwJr1h
And all those entries are separated by new lines. You get the RSA key that you want by asking your session:
所有这些条目都由新行分隔。通过询问会话,您可以获得所需的 RSA 密钥:
session=null;
com.jcraft.jsch.Channel channel =null;
try{
ssh=new JSch();
ssh.setKnownHosts("test");
session=ssh.getSession(userTextField.getText(),ip,22);
session.setPassword(passwordField1.getText());
System.out.println(session.getHostKey());
session.connect();
channel=session.openChannel("sftp");
channel.connect();
ChannelSftp sftp=(ChannelSftp) channel;
System.out.println(sftp.getHome());
for (Object o : sftp.ls(sftp.getHome())) {
System.out.println(((ChannelSftp.LsEntry)o).getFilename());
}
} catch (JSchException e1) {
e1.printStackTrace();
addHost(session.getHostKey().getKey());
} catch (SftpException e1) {
e1.printStackTrace();
}
}
private void addHost(String key){
try {
FileWriter tmpwriter=new FileWriter("test",true);
tmpwriter.append(ip + " ssh-rsa " + key+"\n");
System.out.println(ip + " ssh-rsa " + key);
tmpwriter.flush();
tmpwriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
So session.getHostKey().getKey()
is what you want to call to get the key.
这session.getHostKey().getKey()
就是您要调用以获取密钥的方法。
You also need to call session.connect();
before you ask for the key and handle it in the catch.
您还需要session.connect();
在索要钥匙之前先致电并在抓获中处理它。
回答by Aniket Thakur
As most the of the answers suggest you have to provide know host file but fail to address how to get it. You simply need to SSH to the host.
由于大多数答案都表明您必须提供知道的主机文件,但无法解决如何获取它。您只需要通过 SSH 连接到主机。
Eg ssh [email protected]
例如 ssh [email protected]
when prompted provide password. For first time connection it will you to save the hosts ssh key fingerprint. Once you are connected you can find your known_host file at
提示时提供密码。第一次连接时,您将保存主机 ssh 密钥指纹。连接后,您可以在以下位置找到 known_host 文件
user/.ssh/known_hosts
For me on windows path is C:\Users\athakur\.ssh\known_hosts
. You can directly use this file. Or edit the file and pick up entry from it corresponding to your IP address which would look something like
对我来说,windows 路径是C:\Users\athakur\.ssh\known_hosts
. 你可以直接使用这个文件。或者编辑文件并从中选择与您的 IP 地址相对应的条目,它看起来像
192.168.100.103 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1UsgiLH5hjIScZlqPA4kNhPoXAX00mMv65N8qTvYd1D1M5DwWtTTcxK4w0wGKKVA7RERzWbtjPpSomJwT1LofZr+qafLdiEvhirIXVYHSWZqp6zTJW0jzk3p07ugjoHV3YUWKDzOaiFuOMslt8hD7pZv8nhOYfxBZdsVHdukYRP8MADXC0ZgOD5ZYZ0EglaQJYPG7n73PSMZWZT/oafUcx6bFiRF4QsXaguWuu6umX9gaV7VvoyMJg+kxPAKnGDFY7If61AG7vAchUUhlQ44SB1FFr25y+qeUg2NGqAxH/Z/ZAfvZ+pDv3Cd9s+KCnEIqxyxY/sPQ2zCvwf0Z9fTeQ==
192.168.100.103 SSH-RSA AAAAB3NzaC1yc2EAAAABIwAAAQEA1UsgiLH5hjIScZlqPA4kNhPoXAX00mMv65N8qTvYd1D1M5DwWtTTcxK4w0wGKKVA7RERzWbtjPpSomJwT1LofZr + qafLdiEvhirIXVYHSWZqp6zTJW0jzk3p07ugjoHV3YUWKDzOaiFuOMslt8hD7pZv8nhOYfxBZdsVHdukYRP8MADXC0ZgOD5ZYZ0EglaQJYPG7n73PSMZWZT / oafUcx6bFiRF4QsXaguWuu6umX9gaV7VvoyMJg + kxPAKnGDFY7If61AG7vAchUUhlQ44SB1FFr25y + qeUg2NGqAxH / Z / ZAfvZ + pDv3Cd9s + KCnEIqxyxY / sPQ2zCvwf0Z9fTeQ ==
Note : Host machines SSH fingerprint (based on hosts public key that you can find at /etc/ssh/ssh_host_rsa_key.pub
) may change in SSH is reinstalled in that machine. Or you may encounter MIM attack (even it is for testing sake). In such cases you will have to pick new entry in same way mentioned above.
注意:主机 SSH 指纹(基于您可以在 中找到的主机公钥/etc/ssh/ssh_host_rsa_key.pub
)可能会在 SSH 重新安装在该机器上时发生变化。或者你可能会遇到 MIM 攻击(即使是为了测试)。在这种情况下,您必须以上述相同的方式选择新条目。
回答by sandarovich
Maybe it's no more relevant but in my case, the similar problem was happened with docker-compose.yml in container, that was build from spring-boot application that 100 % worked locally
也许它不再相关,但在我的情况下,类似的问题发生在容器中的 docker-compose.yml 中,它是从 100% 在本地工作的 spring-boot 应用程序构建的
config-service:
image: <host>/<bla>-config-service:<version>
hostname: config-service
ports:
- 3000:3000
depends_on:
- discovery
environment:
- CONSUL_HOST=discovery
- CONSUL_PORT=<port>
- CONFIG_GIT_URI=git@<host>:<group>/<repository>.git
- CONFIG_GIT_BRANCH=development
volumes:
- ~/.ssh/:/root/.ssh/:ro
Solution was to apply hack on ~/.ssh folder.
解决方案是在 ~/.ssh 文件夹上应用 hack。
chcon -Rt svirt_sandbox_file_t ~/.ssh
After that I suppose volumes was correctly mapped between docker container and local machine, and described exception was gone.
之后,我认为卷在 docker 容器和本地机器之间正确映射,并且描述的异常消失了。