我正在尝试使用Jsch在Java中建立SSH连接。我的代码产生以下异常:

com.jcraft.jsch.JSchException: UnknownHostKey: mywebsite.example.
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.example";
            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正常工作)- or - 配置JSch不使用“StrictHostKeyChecking”(这会带来不安全,应该只用于测试目的),使用以下代码: java.util.Properties config = new java.util.Properties(); 配置。把(“StrictHostKeyChecking”、“不”); session.setConfig(配置);

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

其他回答

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

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

jsch.setKnownHosts(knownHostsFileName);

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

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

有关更多细节,请参阅Javadoc。

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

Jsch是开源的,您可以从这里下载源代码。在示例文件夹中,查找KnownHosts.java以了解更多细节。

我会:

尝试从命令行进行ssh并接受公钥(主机将被添加到~/。ssh/known_hosts,然后一切都应该从Jsch正常工作)- or - 配置JSch不使用“StrictHostKeyChecking”(这会带来不安全,应该只用于测试目的),使用以下代码: java.util.Properties config = new java.util.Properties(); 配置。把(“StrictHostKeyChecking”、“不”); session.setConfig(配置);

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

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

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.example", 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;
        }
    }
}

请代入适当的值。

提供主机的rsa公钥:—

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

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

根据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密钥的方法是将它们以非标准格式存储在注册表中,难以提取。