com.jcraft.jsch.JSchException:UnknownHostKey
質問
私は利用しよう Jsch をSSH接続Java.私のコードにより下記の例外:
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);
}
}
}
解決
私なら次のいずれかをします:
- 試してみてください
ssh
コマンドラインから実行し、公開キーを受け入れます(ホストが追加されます)~/.ssh/known_hosts
そうすれば、Jsch からすべてが正常に動作するはずです) -または- 次のコードを使用して、「StrictHostKeyChecking」を使用しないように JSch を構成します (これにより安全性が低下するため、テスト目的のみに使用してください)。
java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config);
オプション #1 (ホストを ~/.ssh/known_hosts
ファイル)には私の好みがあります。
他のヒント
では、セキュリティ上のリスクを避けるホスト鍵をチェックしている。
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がオープンソースおよびダウンロードできますのソースから こちらの.実施例中のフォルダを探すKnownHosts.java もっと知ります。
ケースでもの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
やSHA_RSAをpreferingの代わりに、ローカル Jcraftするに文句を言います> HostKeyAlgorithms の彼らはあまりにも熱心であることを思えませんが、設定する自分のバグがします。
あなたはSSHのために使用するもののプログラムに応じて、適切なキーを取得する方法は変えることができます。 (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の代替を提案することができます。私は抽出することが面倒非標準形式でレジストリに格納することでSSH鍵を扱うパテの方法を見つけます。
ホストのRSA公開鍵を供給: -
String knownHostPublicKey = "mywebsite.com ssh-rsa AAAAB3NzaC1.....XL4Jpmp/";
session.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));
また、次のコードを実行することができます。それは、テストされ、動作してます。
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;
}
}
}
適切な値を代入してください。
あなたは、単に行うことができます。
session.setConfig("StrictHostKeyChecking", "no");
これは、安全ではありません、それはチェックを世界的に知られているホスト鍵を無効になりますように、ライブ環境に適した回避策はありません。
ただ、 "ユーザー"、 "パス"、 "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);
}
}
}
私はこの愚かな問題で多くの時間をロスしました。「アクセスしているファイルにホストがありません」というメッセージは非常に正しいと思いますが、システム上には 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
Windows ホームの C:\Users\ にはありません。my_local_user\.ssh 、私は単にそれらをマージし、問題を解決するために調整しました。
これが将来誰かに役立つことを願っています
既知のホストを設定することfingure印刷設定値よりも良好である。
あなたが知られているホストを設定した場合(アプリケーションが実行される前に、非常に最初の時間)、アプリケーションの実行ボックスからsshを手動にしてみてください。
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");
}
}