com.jcraft.jsch.JSchException:UnknownHostKey


179

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

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

* nixホストでsshdをシャットダウンして、フォアグラウンドで単一のスレッドを開始します。/ usr / sbin / sshd -dこれにより、sshd側から多くのデバッグ情報が得られます。

@AmmSokun 全員がこの問題を解決できました。答えを見てください。
bmargulies

回答:


226

私はどちらかでしょう:

  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ファイルに追加する)が私の好みです。


37
JSch#setConfig("StrictHostKeyChecking", "no")同じ仕事をしますが、たった1行です
yegor256

2
補足:このフィードバックを使用して~/.ssh/config、ソースコードを変更するアクセス権がないときに上記のエラーを修正するようにファイルを構成しました
Adam Rofer

.ssh / configに対して何をしましたか?同じエラーが発生しています。
Bernard Igiri 2012

19
これは安全ではなく、その原則の正しい答えとして選択されるべきではありませんでした。setKnownHosts()およびsetFingerPrint()オプションは、sshプロセスの重要な側面を無視せずにこれを行う方法です。編集:私の経験では、#1はEclipseなどの一部のIDE環境内では機能しません。
ロンド

1
それは日食の中で私のために仕事をしました...私がテスト環境で必要なものだけ....
ProfVersaggi

46

質問は一般的に回答されていますが、既存の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

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


1
私たちも同様のケースで、ecdsa-sha2-nistp384あなたのソリューションは非常にうまく機能しています。そのためにはopenssh-キースキャンマニュアル、および私たちの必要性、我々は実行しますssh-keyscan -t rsa,ecdsa example.org >> known_hosts
taringamberini 2018

1
私はそのような問題を抱えていましたが、例外はJSchException:UnknownHostKeyの代わりにJSchException:reject HostKey:でした(これは他の一部のユーザーに役立つ可能性があります)
bdulac

@krishnakumarpによって提案されたsetKnownHostsファイルを追加する必要がありました
Wolfgang Fahl

34

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

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

jsch.setKnownHosts(knownHostsFileName);

または、以下のように公開キー文字列を使用します。

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

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

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

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


16

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

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

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

たぶん、他の誰かが別のWindowsの代替案を提案できます。私は、SSHキーを抽出するのが面倒な非標準形式でレジストリに格納することによって、SSHキーを処理する方法を見つけました。


Windowsでh sshを使用してcygwinopensslパッケージと依存関係をダウンロードする必要があります)私はダウンロードできました~/.ssh/known_hosts。@CharityAbbottに感謝します。
taringamberini 2015年

10

ホストの公開RSAキーを提供します:-

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

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

1
jschバージョン0.1.50では常に動作しませんでした(常にjschでNPEを取得しました)。最新バージョン0.1.53では動作します。
Udo

Jschコード(Util.byte2str())がUTF-8エンコーディングを想定している場合、これ(String.getBytes())はUnicodeエンコード文字のバイト配列を提供しますか?
リッチp

7

あなたも簡単にできます

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

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


2
このコードは質問への回答に役立ちますが、コードのみの回答は高品質ではありません。より適切な答えは、コードが何を行うかを説明し、どこに挿入するかを伝え、このアプローチが採用された理由を説明し、関連ドキュメントにリンクすることです。
Stephen Ostermiller 2014年

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

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


はい、参照用に追加しました。削除します。ありがとう。
Vishnu Prasad Kallummel 2013

1
これにより、キーボードインタラクティブ認証方式を提供する特定のSSHサーバーに接続するときに、ある種の奇妙な認証問題が発生しました。私は何年もキーのことを取り除くためにそれを使用し、それから特定のサーバーで今日ちょうど燃やされました。私はgetPassword()を介してPWを提供しなかったので、Sessionオブジェクトに直接提供しました。心に留めておきます。もう使いません。
Marc、

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

いいえ、私にはうまくいきません。同様に、エリックLeschinski /ラケッシュAcharyaさんの答えは、私がコメントアウトした場合に失敗しconfig.put("StrictHostKeyChecking", "no"); 、手動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) at com.jcraft.jsch.Session.connect(Session.java:345)
Urhixidur

2013年6月13日に入手可能なJSCHライブラリバージョンを使用して、しばらくしてから、ライブラリで変更が加えられた可能性があります
dalvarezmartinez1

1

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

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


1

私はこの愚かな問題で多くの時間を失いました、そして私は「私がアクセスしているファイルにホストがありません」というメッセージは完全に正しいと思いますが、あなたのシステムでは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ホームではなく、問題を解決するためにそれらを単にマージして整列させました。

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


0

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

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

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


0
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");
}
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.