com.jcraft.jsch.JSchException: UnknownHostKey


179

Saya mencoba menggunakan Jsch untuk membuat koneksi SSH di Jawa. Kode saya menghasilkan pengecualian berikut:

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

Saya tidak dapat menemukan cara memverifikasi kunci host dalam dokumentasi Jsch. Saya telah memasukkan kode saya di bawah ini.

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

Cobalah untuk mematikan sshd pada host * nix Anda, dan mulai utas tunggal di latar depan: / usr / sbin / sshd -d Ini akan memberi Anda banyak informasi debug dari sisi sshd.

@AmmSokun semua orang bisa menyelesaikan masalah ini. Lihat jawabannya.
bmargulies

Jawaban:


226

Saya juga akan:

  1. Cobalah untuk sshdari baris perintah dan menerima kunci publik (tuan rumah akan ditambahkan ke ~/.ssh/known_hostsdan semuanya harus kemudian bekerja dengan baik dari jsch) -ATAU-
  2. Konfigurasikan JSch untuk tidak menggunakan "StrictHostKeyChecking" (ini menimbulkan rasa tidak aman dan hanya digunakan untuk tujuan pengujian), menggunakan kode berikut:

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

Opsi # 1 (menambahkan host ke ~/.ssh/known_hostsfile) memiliki preferensi saya.


37
JSch#setConfig("StrictHostKeyChecking", "no")akan melakukan pekerjaan yang sama, tetapi hanya dalam satu baris
yegor256

2
Catatan: Saya menggunakan umpan balik ini untuk mengonfigurasi ~/.ssh/configfile saya untuk memperbaiki kesalahan di atas ketika saya tidak memiliki akses untuk mengubah kode sumber
Adam Rofer

Apa yang Anda lakukan pada .ssh / config Anda? Saya mengalami kesalahan yang sama.
Bernard Igiri

19
Ini tidak aman dan seharusnya tidak dipilih sebagai jawaban yang tepat untuk prinsip itu. Opsi setKnownHosts () dan setFingerPrint () adalah cara untuk melakukan ini tanpa mengabaikan aspek penting dari proses ssh. Sunting: dalam pengalaman saya, # 1 tidak berfungsi dari dalam beberapa lingkungan IDE seperti Eclipse.
Rondo

1
Itu melakukan pekerjaan untuk saya di dalam gerhana ... hanya apa yang saya butuhkan dalam lingkungan pengujian ....
ProfVersaggi

46

Sementara pertanyaan telah dijawab secara umum, saya telah menemukan diriku bahwa ada kasus ketika bahkan ada known_hosts entri tidak membantu. Ini terjadi ketika server SSH mengirim sidik jari ECDSA dan sebagai hasilnya, Anda akan memiliki entri seperti ini:

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

Masalahnya adalah bahwa JSch lebih suka SHA_RSA dan saat menghubungkannya akan mencoba membandingkan sidik jari SHA-RSA, yang akan menghasilkan kesalahan tentang "host tidak dikenal".

Untuk memperbaiki ini cukup jalankan:

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

atau mengeluh kepada Jcraft tentang lebih memilih SHA_RSA daripada menggunakan pengaturan HostKeyAlgorithms lokal , meskipun mereka tampaknya tidak terlalu bersemangat untuk memperbaiki bug mereka .


1
Kami berada dalam kasus serupa, dengan ecdsa-sha2-nistp384, dan solusi Anda bekerja dengan sangat baik. Sesuai dengan openssh-keyscan manual , dan kebutuhan kita, kita jalankan ssh-keyscan -t rsa,ecdsa example.org >> known_hosts.
taringamberini

1
Saya punya masalah seperti itu, tetapi pengecualiannya adalah JSchException: tolak HostKey: alih-alih JSchException: UnknownHostKey (ini mungkin membantu beberapa pengguna lain)
bdulac

Saya juga harus menambahkan file setKnownHosts seperti yang diusulkan oleh @krishnakumarp
Wolfgang Fahl

34

Ini adalah risiko keamanan untuk menghindari pemeriksaan kunci host.

JSch menggunakan antarmuka HostKeyRepository dan implementasi standarnya kelas FamousHosts untuk mengelola ini. Anda dapat memberikan implementasi alternatif yang memungkinkan kunci tertentu dengan menerapkan HostKeyRepository. Atau Anda dapat menyimpan kunci yang ingin Anda izinkan dalam file dalam format dan panggilan known_hosts

jsch.setKnownHosts(knownHostsFileName);

Atau dengan String kunci publik seperti di bawah ini.

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

lihat Javadoc untuk lebih jelasnya.

Ini akan menjadi solusi yang lebih aman.

Jsch adalah sumber terbuka dan Anda dapat mengunduh sumbernya dari sini . Di folder contoh, cari FamousHosts.java untuk mengetahui lebih detail.


16

Bergantung pada program apa yang Anda gunakan untuk ssh, cara untuk mendapatkan kunci yang tepat bisa bervariasi. Putty (populer dengan Windows) menggunakan format mereka sendiri untuk kunci ssh. Dengan sebagian besar varian Linux dan BSD yang pernah saya lihat, Anda hanya perlu melihatnya ~/.ssh/known_hosts. Saya biasanya ssh dari mesin Linux dan kemudian menyalin file ini ke mesin Windows. Lalu saya menggunakan sesuatu yang mirip dengan

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

Dengan asumsi saya telah menempatkan file di C:\Users\cabbottmesin Windows saya. Jika Anda tidak memiliki akses ke mesin Linux, coba http://www.cygwin.com/

Mungkin orang lain dapat menyarankan alternatif Windows lain. Saya menemukan cara dempul menangani kunci SSH dengan menyimpannya di registri dalam format non-standar yang mengganggu untuk mengekstrak.


Di windows menggunakanh ssh in cygwin(Anda harus mengunduh opensslpaket dan dependensi) saya sudah bisa mengunduh ~/.ssh/known_hosts. Terima kasih kepada @CharityAbbott.
taringamberini

10

Menyediakan kunci publik rsa tuan rumah: -

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

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

1
Tidak bekerja untuk saya dengan jsch versi 0.1.50 (selalu mendapat NPE di jsch) tetapi dengan versi terbaru 0.1.53 berfungsi.
Udo

akankah ini (String.getBytes ()) menyediakan array byte karakter unicode-encode, ketika kode Jsch (Util.byte2str ()) mengharapkan pengkodean UTF-8?
rich p

7

Anda juga bisa melakukannya

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

Ini tidak aman dan ini solusi yang tidak cocok untuk lingkungan hidup karena akan menonaktifkan pemeriksaan kunci host yang dikenal secara global.


2
Meskipun kode ini dapat membantu menjawab pertanyaan, kode hanya jawaban yang tidak berkualitas tinggi. Jawaban yang lebih baik akan menjelaskan apa yang dilakukan kode, memberi tahu di mana memasukkannya, menjelaskan mengapa pendekatan ini diambil, dan tautan ke dokumentasi yang relevan.
Stephen Ostermiller

6

Anda juga dapat menjalankan kode berikut. Ini diuji dan berfungsi.

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

Harap gantikan nilai yang sesuai.


Ya, saya telah menambahkan itu untuk referensi saya. Saya akan menghapus itu. Terima kasih.
Wisnu Prasad Kallummel

1
ini menciptakan semacam masalah auth aneh ketika menghubungkan ke Server SSH tertentu yang menawarkan metode otentikasi keyboard-interaktif. Saya menggunakannya selama bertahun-tahun untuk menyingkirkan Key dan kemudian dibakar hanya hari ini dengan server tertentu. Karena saya tidak memasok PW melalui getPassword () tetapi langsung ke objek Sesi. Ingatlah itu. Saya tidak akan menggunakannya lagi.
Marc

1

Cukup gantikan "pengguna", "pass", "SSHD_IP". Dan buat file bernama known_hosts.txt dengan konten server ~ / .ssh / known_hosts. Anda akan mendapatkan sebuah shell.

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

Tidak tidak bekerja untuk saya. Demikian pula, jawaban Eric Leschinski / Rakesh Acharya gagal jika saya berkomentar config.put("StrictHostKeyChecking", "no"); . ssh -vSambungan manual mengungkapkan .ssh/known_hostsfile tersebut memang berisi kunci ( ecdsa-sha2-nistp256) tetapi kode melakukan ini: 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

Sudah lama, apa yang saya coba lakukan, adalah menggunakan versi perpustakaan JSCH yang tersedia pada 13 Juni 2013, karena hal-hal yang mungkin berubah di perpustakaan sejak saat itu
dalvarezmartinez1

1

pengaturan host yang dikenal lebih baik daripada pengaturan nilai cetak fingure.

Ketika Anda mengatur host yang dikenal, coba ssh secara manual (pertama kali, sebelum aplikasi berjalan) dari kotak aplikasi berjalan.


1

Saya kehilangan banyak waktu karena masalah bodoh ini, dan saya pikir pesannya benar "tidak ada host di file yang saya akses" tetapi Anda dapat memiliki lebih dari satu file know_host di sistem Anda (sebagai contoh saya Saya menggunakan mobaXterm dan menyimpannya sendiri di dalam direktori instalasi yang me-mount rumah dari root itu).

Jika Anda mengalami: itu bekerja dari baris perintah tetapi tidak dari aplikasi mencoba untuk mengakses ke server jauh Anda dengan ssh dan periksa dengan verbose -v opsi file mana yang saat ini digunakan contoh berikut:

 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

seperti yang Anda lihat kunci ditemukan di:

debug1: Found key in /home/mobaxterm/.ssh/known_hosts:19

dan tidak di jendela rumah saya di bawah C: \ Users \ my_local_user \ .ssh, saya hanya menggabungkan mereka dan disejajarkan untuk menyelesaikan masalah.

Semoga ini bisa membantu seseorang di masa depan


0

Adakah yang bisa menyelesaikan masalah ini? Saya menggunakan Jscp untuk scp file menggunakan otentikasi kunci publik (saya tidak ingin menggunakan otentikasi kata sandi). Bantuan akan dihargai !!!

Entri stackoverflow ini adalah tentang pemeriksaan kunci-host, dan tidak ada kaitannya dengan otentikasi kunci publik.

Adapun otentikasi kunci publik, coba sampel berikut dengan kunci privat Anda (non ciphered),


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");
}
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.