programing

com.jcraft.jsch를 클릭합니다.JSch Exception:알 수 없는 호스트 키

shortcode 2022. 11. 24. 20:51
반응형

com.jcraft.jsch를 클릭합니다.JSch Exception:알 수 없는 호스트 키

Java에서 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);
        } 
    }
}

다음 중 하나를 선택합니다.

  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_hostsfile 제 .

일반적으로는 질문에 답했지만, 기존의 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

Jcraft에게 로컬 HostKeyAlgorithms 설정을 사용하는 대신 SHA_RSA를 선호하는 것에 대해 불만을 제기할 수도 있습니다.다만, Jcraft는 버그를 수정하고 싶다고는 생각하지 않는 것 같습니다.

호스트 키 검사를 피하는 것은 보안상의 위험입니다.

JSch는 HostKeyRepository 인터페이스와 기본 구현 KnownHosts 클래스를 사용하여 이를 관리합니다.HostKeyRepository를 구현함으로써 특정 키를 허용하는 대체 구현을 제공할 수 있습니다.또는 허용할 키를 known_hosts 형식으로 파일에 저장하고 호출할 수 있습니다.

jsch.setKnownHosts(knownHostsFileName);

또는 다음과 같은 공개 키 String을 사용합니다.

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

자세한 내용은 Javadoc을 참조하십시오.

이것이 보다 안전한 해결책이 될 것입니다.

Jsch는 오픈 소스이며 여기서 소스를 다운로드할 수 있습니다.예제 폴더에서 KnownHosts.java를 검색하여 자세한 내용을 확인하십시오.

ssh에 다를 수 .ssh 에 、 ssh 、 h could 、 를 depending depending를를를를를 。Putty(Windows 서서는는는는는는는는는는 put put put put put put put put put put put put put put put put put put put 。 및 BSD를 됩니다.~/.ssh/known_hosts「Linux」 「ssh」 「Ssh」 「Ssh」 「Windows」를 참조해 주세요」 저는 이런 걸.

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

파일을 다음 위치에 배치했다고 가정합니다.C:\Users\cabbottWindows 머신에서 사용할 수 있습니다.Linux 머신에 액세스 할 수 없는 경우는, http://www.cygwin.com/ 를 사용해 주세요.

다른 사용자가 다른 Windows 대안을 제안할 수도 있습니다.SSH 키를 비표준 포맷으로 레지스트리에 저장하는 퍼티의 취급 방법은 추출하기가 귀찮습니다.

호스트의 공개 rsa 키 제공:-

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

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

간단하게 할 수도 있습니다.

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

안전하지 않고, 글로벌하게 알려진 호스트 키 검사를 사용하지 않도록 설정하기 때문에 실제 환경에 적합하지 않은 해결 방법입니다.

다음 코드를 실행할 수도 있습니다.테스트되어 동작하고 있습니다.

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

적절한 값으로 대체해 주세요.

이 멍청한 문제로 인해 많은 시간을 허비했습니다.메시지는 "접근하는 파일에 호스트가 없습니다"라고 하는 것은 맞지만, 시스템에 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는 단순히 통합하고 문제를 해결하기 위해 정렬했습니다.

이것이 미래에 누군가에게 도움이 되기를 바란다.

"user", "pass", "SSHD_IP"로 대체합니다.그리고 known_hosts라는 파일을 만듭니다.서버의 ~/.disc/known_disc의 콘텐츠와 함께 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);
    }
  }
}

핑거 인쇄 값을 설정하는 것보다 알려진 호스트를 설정하는 것이 좋습니다.

기존의 호스트를 설정하는 경우는, 애플리케이션이 실행되고 있는 박스에서 수동으로 ssh(어플리케이션이 실행되기 전에 처음)를 시험해 주세요.

이 문제를 해결할 수 있는 사람이 있나요?Jscp를 사용하여 공개키 인증을 사용하여 파일을 scp하고 있습니다(패스워드 인증은 사용하지 않습니다).도와주시면 감사하겠습니다!!!

이 stackoverflow 엔트리는 호스트 키체크에 관한 것으로 공개 키 인증과는 관계가 없습니다.

공개키 인증에 대해서는, 다음의 샘플로, 플레인(암호화되어 있지 않은) 개인키를 사용해 주세요.

해답은 @Jairo Martinez가 쓴 삭제된 답변 중 하나에서 찾았습니다.

먼저 서버는 호스트를 해시된 rsa로 저장해야 합니다.

ssh-keyscan -H -t rsa SERVER_IP_ADDRESS >> known_hosts_file

또한 호스트 키가 해시되었음을 Jsch에게 알려야 했습니다.

세션입니다.setConfig("HashKnownHosts", "yes");

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

언급URL : https://stackoverflow.com/questions/2003419/com-jcraft-jsch-jschexception-unknownhostkey

반응형