com.jcraft.jsch.JSchException: UnknownHostKey


179

मैं जावा में 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);
        } 
    }
}

अपने * निक्स होस्ट पर sshd को बंद करने की कोशिश करें, और अग्रभूमि में एक भी धागा शुरू करें: / usr / sbin / sshd -d यह आपको sshd पक्ष से बहुत डिबगिंग जानकारी देगा।

@AmmSokun हर कोई इस समस्या को हल करने में सक्षम है। जवाब देखिए।
bmargulies

जवाबों:


226

मैं या तो:

  1. करने की कोशिश करो sshकमांड लाइन से और सार्वजनिक कुंजी को स्वीकार (मेजबान में जोड़ दिया जाएगा ~/.ssh/known_hostsऔर सब कुछ तो Jsch से काम ठीक करना चाहिए) -या-
  2. JSch को कॉन्फ़िगर करें "StrictHostKeyChecking" का उपयोग न करने के लिए (यह असुरक्षा का परिचय देता है और केवल परीक्षण उद्देश्यों के लिए उपयोग किया जाना चाहिए), निम्न कोड का उपयोग करते हुए:

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

विकल्प # 1 ( ~/.ssh/known_hostsफ़ाइल में होस्ट को जोड़ना ) मेरी प्राथमिकता है।


37
JSch#setConfig("StrictHostKeyChecking", "no")एक ही काम करेंगे, लेकिन सिर्फ एक लाइन में
yegor256

2
साइड नोट: मैंने ~/.ssh/configउपरोक्त त्रुटि को ठीक करने के लिए अपनी फ़ाइल को कॉन्फ़िगर करने के लिए इस फीडबैक का उपयोग किया जब मेरे पास स्रोत कोड को संशोधित करने के लिए एक्सेस नहीं था
एडम रॉफर

आपने अपने .ssh / config के साथ क्या किया? मैं एक ही त्रुटि कर रहा हूँ।
बर्नार्ड इगिरि

19
यह असुरक्षित है और वास्तव में उस सिद्धांत पर सही उत्तर के रूप में नहीं चुना जाना चाहिए था। SetKnownHosts () और setFingerPrint () विकल्प ssh प्रक्रिया के एक महत्वपूर्ण पहलू की अनदेखी किए बिना ऐसा करने का तरीका है। संपादित करें: मेरे अनुभव में, # 1 ग्रहण जैसे कुछ आईडीई वातावरण के भीतर से काम नहीं करता है।
रोंडो

1
इसने मेरे लिए ग्रहण के अंदर काम किया ... बस एक परीक्षण के माहौल में मुझे क्या चाहिए ....
प्रोविर्सगि

46

हालांकि इस सवाल का जवाब सामान्य तौर पर दिया गया है, मैंने खुद को पाया है कि ऐसा मामला है जब मौजूदा ज्ञात_होस्ट्स एंट्री से भी मदद नहीं मिलती है। यह तब होता है जब एक SSH सर्वर ECDSA फिंगरप्रिंट भेजता है और परिणामस्वरूप, आपके पास इस तरह एक प्रविष्टि होगी:

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

समस्या यह है कि जेएसएच SHA_RSA पसंद करता है और इसे कनेक्ट करते समय SHA-RSA फिंगरप्रिंट की तुलना करने की कोशिश करेगा, जिसके परिणामस्वरूप "अज्ञात होस्ट" के बारे में त्रुटि होगी।

इसे ठीक करने के लिए बस चलाएं:

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

या स्थानीय HostKeyAl एल्गोरिदम सेटिंग का उपयोग करने के बजाय SHA_RSA पसंद करने के बारे में Jcraft से शिकायत करें , हालांकि वे अपने कीड़े को ठीक करने के लिए बहुत उत्सुक नहीं लगते हैं


1
हम एक समान मामले में हैं ecdsa-sha2-nistp384, और आपके समाधान बहुत अच्छी तरह से काम करते हैं। तदनुसार ओपनश-कीस्कैन मैनुअल , और हमारी जरूरत, हम चलाते हैं ssh-keyscan -t rsa,ecdsa example.org >> known_hosts
तारिंगमबरीनी

1
मुझे इस तरह की समस्या थी, लेकिन अपवाद JSchException: HostKey को अस्वीकार करना: JSchException के बजाय : UnknownHostKey (यह कुछ अन्य उपयोगकर्ताओं की मदद कर सकता है)
bdulac

मुझे इसके अलावा @krishnakumarp द्वारा प्रस्तावित के रूप में setKnownHosts फ़ाइल को जोड़ना था
वोल्फगैंग

34

यह मेजबान कुंजी जाँच से बचने के लिए एक सुरक्षा जोखिम है।

JSch इसे प्रबंधित करने के लिए HostKeyRepository इंटरफ़ेस और इसके डिफ़ॉल्ट कार्यान्वयन KnownHosts वर्ग का उपयोग करता है। आप एक वैकल्पिक कार्यान्वयन प्रदान कर सकते हैं जो HostKeyRepository को लागू करके विशिष्ट कुंजी की अनुमति देता है। या आप उन कुंजियों को रख सकते हैं, जिन्हें आप एक फाइल में ज्ञात_होस्ट्स प्रारूप में अनुमति देना चाहते हैं और कॉल करना चाहते हैं

jsch.setKnownHosts(knownHostsFileName);

या नीचे के रूप में एक सार्वजनिक कुंजी स्ट्रिंग के साथ।

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

देख जावाडोक अधिक जानकारी के लिए।

यह एक अधिक सुरक्षित समाधान होगा।

Jsch ओपन सोर्स है और आप यहाँ से सोर्स डाउनलोड कर सकते हैं । उदाहरण फ़ोल्डर में, अधिक विवरण जानने के लिए KnownHosts.java देखें।


16

आप ssh के लिए किस प्रोग्राम का उपयोग करते हैं इसके आधार पर, उचित कुंजी प्राप्त करने का तरीका भिन्न हो सकता है। पोटीन (विंडोज के साथ लोकप्रिय) ssh कुंजियों के लिए अपने स्वयं के प्रारूप का उपयोग करता है। लिनक्स और बीएसडी के अधिकांश संस्करणों के साथ जो मैंने देखा है, आपको बस अंदर देखना होगा ~/.ssh/known_hosts। मैं आमतौर पर एक लिनक्स मशीन से ssh करता हूं और फिर इस फाइल को विंडोज मशीन में कॉपी करता हूं। फिर मैं कुछ इसी तरह का उपयोग करता हूं

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

यह मानते हुए कि मैंने C:\Users\cabbottअपनी विंडोज मशीन में फाइल को रखा है । यदि आपके पास लिनक्स मशीन नहीं है, तो http://www.cygwin.com/ पर जाएं।

हो सकता है कि कोई और व्यक्ति दूसरे विंडोज विकल्प का सुझाव दे सकता है। मुझे लगता है कि पोटीन को गैर-मानक प्रारूप में रजिस्ट्री में स्टोर करके निकालने के लिए SSH कुंजी को संभालने का तरीका है।


cygwin(आप opensslपैकेज और निर्भरता डाउनलोड करने के लिए है) का उपयोग करते हुए खिड़कियों पर ssh मैं डाउनलोड करने में सक्षम है ~/.ssh/known_hosts। @CharityAbbott को धन्यवाद।
तारिणीमबरीनी

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 के साथ मेरे काम के साथ।
उडो

क्या यह (String.getBytes ()) यूनिकोड-एन्कोडेड वर्णों की बाइट सरणी प्रदान करेगा, जब Jsch कोड (Util.byte2str ()) UTF-8 एन्कोडिंग की उम्मीद करता है?
अमीर पी।

7

आप भी बस कर सकते हैं

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

यह सुरक्षित नहीं है और यह लाइव वातावरण के लिए उपयुक्त नहीं है क्योंकि यह विश्व स्तर पर ज्ञात होस्ट कुंजियों को निष्क्रिय कर देगा।


2
हालांकि यह कोड प्रश्न का उत्तर देने में मदद कर सकता है, केवल कोड उच्च गुणवत्ता वाले नहीं हैं। एक बेहतर उत्तर यह समझाता है कि कोड क्या करता है, यह बताएं कि इसे कहां डालें, बताएं कि यह दृष्टिकोण क्यों लिया गया था, और प्रासंगिक दस्तावेज से लिंक करें।
स्टीफन ओस्टरमिलर

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

कृपया उचित मूल्यों को स्थानापन्न करें।


हां, मैंने इसे अपने संदर्भ के लिए जोड़ा था। मैं उसे हटा दूंगा। धन्यवाद।
विष्णु प्रसाद कल्लुमेल

1
कीबोर्ड-इंटरैक्टिव प्रमाणीकरण विधि की पेशकश करने वाले कुछ SSH सर्वर से कनेक्ट होने पर यह कुछ प्रकार की अजीब समस्याएँ पैदा करता है। मैंने सालों तक इसका इस्तेमाल किया और चाबी से छुटकारा पा लिया और फिर आज एक निश्चित सर्वर से जला दिया गया। क्योंकि मैं getPassword () के माध्यम से पीडब्लू की आपूर्ति करता था, लेकिन सीधे सत्र ऑब्जेक्ट पर। यह याद रखना। मैं इसे अब और इस्तेमाल नहीं करूँगा।
मार्क

1

बस "उपयोगकर्ता", "पास", "SSHD_IP" स्थानापन्न करें। और सर्वर के ~ / .ssh / ज्ञात_होस्ट की सामग्री के साथ ज्ञात_हॉट्स.टैक्स नामक एक फ़ाइल बनाएँ। आपको एक खोल मिलेगा।

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

नहीं मेरे लिए काम नहीं करता है। इसी तरह, एरिक लेसिंस्की / राकेश आचार्य का जवाब विफल रहता है अगर मैं टिप्पणी करता हूं कि 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)
उरहिकिदुर

यह कुछ समय हो गया है, मैं क्या करने की कोशिश कर रहा हूं, 13 जून 2013 को उपलब्ध JSCH लाइब्रेरी संस्करण का उपयोग कर रहा है, क्योंकि तब से संभवत: लाइब्रेरी में चीजें बदल गई हैं
dalvarezmartinez1

1

ज्ञात होस्ट की स्थापना फ़िंगर प्रिंट मान सेट करने से बेहतर है।

जब आप ज्ञात होस्ट सेट करते हैं, तो एप्लिकेशन चलने वाले बॉक्स से मैन्युअल रूप से ssh (पहली बार, एप्लिकेशन चलने से पहले) करने का प्रयास करें।


1

मैं इस बेवकूफ मुद्दे पर बहुत समय गंवाता हूं, और मुझे लगता है कि संदेश काफी सही है "फ़ाइल में होस्ट नहीं है जो मैं एक्सेस कर रहा हूं" लेकिन आपके सिस्टम पर आपके पास know_host फ़ाइल से अधिक हो सकता है (उदाहरण के लिए i 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

और C: \ Users \ के अंतर्गत मेरी विंडो होम में नहीं my_local_user के \ , मैंने बस उन्हें मर्ज कर दिया और समस्या को हल करने के लिए गठबंधन किया।

आशा है कि यह भविष्य में किसी की मदद करेगा


0

क्या कोई इस समस्या को हल करने में सक्षम है? मैं सार्वजनिक कुंजी प्रमाणीकरण (मैं पासवर्ड प्रमाणीकरण का उपयोग नहीं करना चाहता) का उपयोग कर Jscp फ़ाइलों का उपयोग कर रहा हूँ। मदद की सराहना की जाएगी !!!

यह स्टैकओवरफ़्लो प्रविष्टि होस्ट-की जाँच के बारे में है, और इसका सार्वजनिक कुंजी प्रमाणीकरण से कोई संबंध नहीं है।

सार्वजनिक कुंजी प्रमाणीकरण के लिए, अपने सादे (गैर सिफर) निजी कुंजी के साथ निम्नलिखित नमूने का प्रयास करें ,


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");
}
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.