سؤال

أحاول استخدام JSCH. لإنشاء اتصال 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);
        } 
    }
}
هل كانت مفيدة؟

المحلول

أود إما:

  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 ملف) لديه تفضيل بلدي.

نصائح أخرى

إنه مخاطر أمنية لتجنب فحص المفتاح المضيف.

يستخدم JSCH واجهة HostKeyreposidesoration وطبق تنفيذها الافتراضي في إدارة هذا. يمكنك تقديم تطبيق بديل يسمح بمفاتيح محددة عن طريق تنفيذ HostKeyRepository. أو يمكنك الاحتفاظ بالمفاتيح التي تريد السماح بها في ملف في format_hosts و اتصل

jsch.setKnownHosts(knownHostsFileName);

أو مع سلسلة المفاتيح العامة على النحو التالي.

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

يرى جافادوك لمزيد من التفاصيل.

سيكون هذا حلا أكثر أمانا.

JSCH مفتوح المصدر ويمكنك تنزيل المصدر من هنا. وبعد في مجلد الأمثلة، ابحث عن ankhhosts.java لمعرفة المزيد من التفاصيل.

في حين تم الرد على السؤال بشكل عام، فقد وجدت نفسي أن هناك قضية عندما حتى القائمة areh_hosts الدخول لا يساعد. يحدث هذا عندما يرسل خادم SSH بصمات ECDSA ونتيجة لذلك، سيكون لديك إدخال مثل هذا:

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

المشكلة هي أن JSCH تفضل SHA_RSA وبينما يربطه سيحاول مقارنة بصمات الأصابع Sha-RSA، والتي ستؤدي إلى خطأ حول "المضيف غير المعروف".

لإصلاح هذا التشغيل ببساطة:

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

أو يشكو من Jcrcraft. حول أفضل sha_rsa بدلا من استخدام المحلية Hostkeyalgorithms. الإعداد، على الرغم من أنهم لا يبدو أنهم أيضا حريص لإصلاحهم البق.

اعتمادا على البرنامج الذي تستخدمه ل SSH، قد تختلف طريقة الحصول على المفتاح الصحيح. المعجون (شعبية مع Windows) يستخدم تنسيقها الخاص لمفاتيح SSH. مع معظم أنواع Linux و BSD التي رأيتها، عليك فقط أن ننظر ~/.ssh/known_hosts. وبعد أنا عادة SSH من آلة Linux ثم انسخ هذا الملف إلى جهاز Windows. ثم أستخدم شيئا مشابها ل

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

على افتراض أنني وضعت الملف في C:\Users\cabbott على جهاز Windows الخاص بي. إذا لم يكن لديك إمكانية الوصول إلى جهاز 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". وإنشاء ملف يسمى Nearge_hosts.txt مع محتوى الخادم ~ / .ssh / nearch_hosts. سوف تحصل على قذيفة.

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

لقد فقدت الكثير من الوقت في هذه المشكلة الغبية، وأعتقد أن الرسالة محق تماما "لا يوجد المضيف في الملف الذي يمكنني الوصول إليه" ولكن يمكنك الحصول على أكثر من ملف معرفة موجود في نظامك (كمثال "M باستخدام 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

وليس في Windows Home ضمن C: المستخدمينmy_local_user..ssh، أنا ببساطة دمجها ومحاذاة لحل المشكلة.

آمل أن يساعد هذا شخص ما في المستقبل

هل تمكن أي شخص من حل هذه المشكلة؟ أنا أستخدم JSCP إلى ملفات SCP باستخدام مصادقة المفتاح العام (لا أريد استخدام مصادقة كلمة المرور). سوف تكون موضع تقدير المساعدة!

هذا الدخول Stackoverflow يدور حول التحقق من مفتاح المضيف، ولا توجد علاقة بمصادقة المفتاح العام.

بالنسبة لمصادقة المفتاح العام، جرب بعد العينة مع مفتاح Private Private الخاص بك (غير تشفير)،

وضع المضيف المعروف هو أفضل من إعداد قيمة طباعة الكرام.

عند تعيين المضيف المعروف، حاول 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");
}
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top