com.jcraft.jsch.JSchException : UnknownHostKey


179

Jsch 를 사용 하여 Java에서 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);
        } 
    }
}

* nix 호스트에서 sshd를 종료하고 포 그라운드에서 단일 스레드를 시작하십시오. / usr / sbin / sshd -d 이것은 sshd 측에서 많은 디버깅 정보를 제공합니다.

@AmmSokun 모두 가이 문제를 해결할 수있었습니다. 답을보십시오.
bmargulies

답변:


226

나도 :

  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_hosts파일에 추가 )이 선호됩니다.


37
JSch#setConfig("StrictHostKeyChecking", "no")동일한 작업을 수행하지만 한 줄에
yegor256

2
참고 :이 피드백을 사용 ~/.ssh/config하여 소스 코드를 수정할 권한이 없을 때 위의 오류를 수정 하도록 파일 을 구성했습니다.
Adam Rofer

.ssh / config로 무엇을 했습니까? 같은 오류가 발생했습니다.
Bernard Igiri

19
이것은 안전하지 않으며 실제로 그 원칙에 대한 정답으로 선택되어서는 안됩니다. setKnownHosts () 및 setFingerPrint () 옵션은 ssh 프로세스의 중요한 측면을 무시하지 않고이를 수행하는 방법입니다. 편집 : 내 경험상 # 1은 Eclipse와 같은 일부 IDE 환경에서는 작동하지 않습니다.
Rondo

1
그것은 일식 내에서 나를 위해 일을 ... 테스트 환경에서 필요한 바로 ....
ProfVersaggi

46

이 질문은 일반적으로 답변되었지만 기존 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

또는 로컬 HostKeyAlgorithms 설정 을 사용하는 대신 SHA_RSA 를 선호 하는 것에 대해 Jcraft 에 불만을 제기 하지만 버그 를 수정 하기에는 너무 열망 하지는 않습니다 .


1
우리는와 비슷한 경우 ecdsa-sha2-nistp384에 있으며 귀하의 솔루션은 매우 잘 작동합니다. 따라서로 는 openssh-키 스캔 매뉴얼 , 그리고 우리의 필요, 우리는 실행 ssh-keyscan -t rsa,ecdsa example.org >> known_hosts.
taringamberini 2019

1
나는 그런 문제가 있었지만 예외는 있었다 JSchException : 호스트 키를 거부 : 대신 UnknownHostKey가 : JSchException가 (이 일부 다른 사용자에게 도움이 될 수 있습니다)
bdulac

@krishnakumarp 제안한 나는 추가로 setKnownHosts 파일을 추가했다
볼프강 Fahl

34

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

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를 찾아 자세한 내용을 확인하십시오.


16

ssh에 사용하는 프로그램에 따라 적절한 키를 얻는 방법이 다를 수 있습니다. 퍼티 (Windows에서 인기)는 ssh 키에 대해 자체 형식을 사용합니다. 내가 본 Linux와 BSD의 대부분의 변종은에서 찾아보아야한다 ~/.ssh/known_hosts. 나는 보통 리눅스 머신에서 ssh를 한 다음이 파일을 윈도우 머신으로 복사한다. 그런 다음 비슷한 것을 사용합니다.

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

파일을 C:\Users\cabbottWindows 컴퓨터에 저장했다고 가정 합니다. Linux 시스템에 액세스 할 수 없으면 http://www.cygwin.com/을 시도 하십시오

다른 사람이 다른 Windows 대안을 제안 할 수 있습니다. SSH 키를 레지스트리에 비표준 형식으로 저장하여 추출하는 귀찮은 퍼티 방식을 발견했습니다.


inh ssh를 사용하는 Windows cygwin( openssl패키지 및 종속성 을 다운로드해야 함)에서 다운로드 할 수있었습니다 ~/.ssh/known_hosts. @CharityAbbott에게 감사합니다.
taringamberini

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에서는 작동합니다.
우도

Jsch 코드 (Util.byte2str ())가 UTF-8 인코딩을 기대할 때 this (String.getBytes ())는 유니 코드로 인코딩 된 문자의 바이트 배열을 제공합니까?
rich p

7

간단하게 할 수도 있습니다

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

안전하지 않으며 전 세계적으로 알려진 호스트 키 검사를 비활성화하므로 라이브 환경에 적합하지 않은 해결 방법입니다.


2
이 코드는 질문에 대답하는 데 도움이 될 수 있지만 코드 만 답변하는 것은 품질이 좋지 않습니다. 더 나은 대답은 코드의 기능을 설명하고 코드를 삽입 할 위치를 알려주며이 방법을 사용한 이유를 설명하고 관련 문서에 연결합니다.
Stephen Ostermiller

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 서버에 연결할 때 이상한 인증 문제가 발생했습니다. 몇 년 동안 Key를 제거하고 특정 서버로 오늘 화상을 입었습니다. getPassword ()를 통해 PW를 제공하지 않았지만 Session 객체에 직접 제공했기 때문입니다. 명심하십시오. 나는 더 이상 그것을 사용하지 않을 것입니다.
Marc

1

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

아니, 저에게는 효과가 없습니다. 마찬가지로, Eric Leschinski / Rakesh Acharya의 답변은 내가 주석을 config.put("StrictHostKeyChecking", "no");ssh -v.ssh/known_hostsecdsa-sha2-nistp256com.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)
달면

시간이 흘렀습니다. 2013 년 6 월 13 일에 제공되는 JSCH 라이브러리 버전을 사용하는 것이 그 이후로 라이브러리에서 변경되었을 가능성이 있습니다.
dalvarezmartinez1

1

알려진 호스트 설정은 fingure 인쇄 값을 설정하는 것보다 낫습니다.

알려진 호스트를 설정하면 응용 프로그램이 실행되는 상자에서 수동으로 ssh (응용 프로그램이 실행되기 전에 처음으로)를 시도하십시오.


1

나는이 어리석은 문제에 대해 많은 시간을 잃어 버렸습니다. 메시지가 "액세스하는 파일에 호스트가 없습니다"라는 메시지가 옳다고 생각하지만 시스템에서 know_host 파일 이상을 가질 수 있습니다 (예 : i '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 내 Windows 홈이 아닌 단순히 병합하여 문제를 해결하기 위해 정렬했습니다.

이것이 미래의 누군가를 돕기를 바랍니다.


0

누구든지이 문제를 해결할 수 있었습니까? 공개 키 인증을 사용하여 파일을 scp하기 위해 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");
}
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.