199

JavaでSSH接続を確立するためにJschを使用しようとしています。私のコードは次の例外を生成します:

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

13 に答える 13

252

私は次のいずれかを行います:

  1. sshコマンドラインから試して、公開鍵を受け入れます (ホストが追加され~/.ssh/known_hosts、Jsch からすべてが正常に機能するはずです) -または-
  2. 次のコードを使用して、「StrictHostKeyChecking」を使用しないように JSch を構成します (これはセキュリティ上の問題を引き起こすため、テスト目的でのみ使用する必要があります)。

    java.util.Properties config = new java.util.Properties(); 
    config.put("StrictHostKeyChecking", "no");
    session.setConfig(config);
    

オプション#1(ホストを~/.ssh/known_hostsファイルに追加する)が私の好みです。

于 2010-01-05T00:57:12.840 に答える
65

質問は一般的に回答されていますが、既存のknown_hostsエントリでさえ役に立たない場合があることに気付きました。これは、SSH サーバーが ECDSA フィンガープリントを送信したときに発生し、その結果、次のようなエントリが作成されます。

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

問題は、JSchSHA_RSA を優先し、接続中に SHA-RSA フィンガープリントを比較しようとするため、「不明なホスト」に関するエラーが発生することです。

これを修正するには、次を実行します。

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

または、ローカルのHostKeyAlgorithms設定を使用する代わりに SHA_RSA を好むことについてJcraftに不平を言いますが、彼らはバグを修正することに熱心ではないようです。

于 2017-06-27T09:53:32.300 に答える
44

ホスト キーのチェックを回避することは、セキュリティ リスクです。

JSch は HostKeyRepository インターフェイスとそのデフォルト実装の KnownHosts クラスを使用してこれを管理します。HostKeyRepository を実装することで、特定のキーを許可する代替実装を提供できます。または、許可するキーをknown_hosts形式のファイルに保持して呼び出すこともできます

jsch.setKnownHosts(knownHostsFileName);

または、以下のように公開鍵 String を使用します。

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

詳細については、 Javadocを参照してください。

これは、より安全なソリューションになります。

Jsch はオープン ソースであり、ここからソースをダウンロードできます。サンプル フォルダーで、KnownHosts.java を探して詳細を確認します。

于 2012-12-24T11:13:51.543 に答える
17

ssh に使用するプログラムによって、適切なキーを取得する方法が異なる場合があります。Putty (Windows で人気) は、独自の形式の ssh キーを使用します。私が見た Linux と BSD のほとんどの亜種では、~/.ssh/known_hosts. 私は通常、Linux マシンから ssh を実行してから、このファイルを Windows マシンにコピーします。次に、似たようなものを使用します

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

C:\Users\cabbottファイルをWindows マシンに配置したと仮定します。Linux マシンにアクセスできない場合は、http://www.cygwin.com/を試してください。

他の誰かが別の Windows の代替案を提案できるかもしれません。SSH キーを標準外の形式でレジストリに格納することによって SSH キーを処理するパテの方法は、抽出するのが面倒だと思います。

于 2012-12-24T18:41:10.453 に答える
8

単純に行うこともできます

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

安全ではなく、グローバルに知られているホストキーのチェックを無効にするため、ライブ環境には適していない回避策です。

于 2014-06-20T09:40:09.653 に答える
6

次のコードを実行することもできます。テストされ、動作しています。

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

適切な値に置き換えてください。

于 2013-01-22T11:45:32.967 に答える
2

私はこのばかげた問題で多くの時間を失いました.「アクセスしているファイルにホストがありません」というメッセージは非常に正しいと思いますが、システムには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

C:\Users\ my_local_user \.ssh の下の私のWindowsホームではなく、問題を解決するためにそれらをマージして調整しました。

これが将来誰かを助けることを願っています

于 2016-09-28T09:46:16.407 に答える
1

既知のホストを設定する方が、フィンガープリント値を設定するよりも優れています。

既知のホストを設定するときは、アプリケーションが実行されるボックスから手動でsshを実行してみてください(アプリケーションが実行される前に、初めて)。

于 2013-02-02T01:34:33.507 に答える
1

「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);
    }
  }
}
于 2013-06-13T13:33:15.167 に答える
0

誰もこの問題を解決できましたか? Jscp を使用して、公開鍵認証を使用してファイルを scp しています (パスワード認証を使用したくありません)。助けていただければ幸いです!!!

このstackoverflowエントリーはホストキーチェックに関するもので、公開鍵認証とは関係ありません。

公開鍵認証については、プレーンな (暗号化されていない) 秘密鍵を使用して次のサンプルを試してください。

于 2012-12-25T15:19:46.387 に答える
0

@Jairo Martínezによって書かれた削除された回答の1つで解決策を見つけました

まず、サーバーはホストをハッシュされた rsa として保存する必要があります

ssh-keyscan -H -t rsa SERVER_IP_ADDRESS >> 既知のホスト ファイル

さらに、ホストキーがハッシュされていることを Jsch に伝える必要がありました。

session.setConfig("HashKnownHosts", "はい");

于 2021-11-22T14:28:41.830 に答える
-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");
}
于 2013-12-20T06:43:36.490 に答える