문제

사용하려고합니다 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);
        } 
    }
}
도움이 되었습니까?

해결책

나는 둘 중 하나입니다 :

  1. 하려고 노력하다 ssh 명령 줄에서 공개 키를 수락합니다 (호스트가 추가됩니다. ~/.ssh/known_hosts 그런 다음 모든 것이 JSCH에서 잘 작동해야합니다) -또는-
  2. 다음 코드를 사용하여 "StricthostkeyEchecking"을 사용하지 않도록 JSCH가 "StricThostKeyChecking"(불안감을 소개하며 테스트 목적으로 만 사용해야 함)을 구성하십시오.

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

옵션 #1 (호스트 추가 ~/.ssh/known_hosts 파일)이 선호합니다.

다른 팁

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

JSCH는 HostKeyRepository 인터페이스와 기본 구현으로 알려진 호스트 클래스를 사용하여이를 관리합니다. HostKeyRepository를 구현하여 특정 키를 허용하는 대체 구현을 제공 할 수 있습니다. 또는 파일에서 허용하려는 키를 알려진_hosts 형식 그리고 전화

jsch.setKnownHosts(knownHostsFileName);

또는 아래와 같이 공개 키 문자열이 있습니다.

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

보다 Javadoc 자세한 사항은.

이것은보다 안전한 솔루션이 될 것입니다.

JSCH는 오픈 소스이며 소스를 다운로드 할 수 있습니다. 여기. 예제 폴더에서는 알려진 hosts.java를 찾으려면 자세한 내용을 알 수 있습니다.

질문이 일반적으로 응답되었지만, 나는 나 자신이 사례 기존의 경우 알려진_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 로컬을 사용하는 대신 SHA_RSA를 선호합니다 hostkeyalgorithms 설정, 비록 그것들도 그렇지 않은 것 같습니다 열렬한 그들의 고치기 위해 버그.

SSH에 사용하는 프로그램에 따라 적절한 키를 얻는 방법은 다를 수 있습니다. Putty (Windows에서 인기)는 SSH 키에 자체 형식을 사용합니다. 내가 본 Linux와 BSD의 대부분의 변형으로, 당신은 ~/.ssh/known_hosts. 나는 일반적으로 Linux 시스템에서 SSH를 한 다음이 파일을 Windows 시스템에 복사합니다. 그런 다음 비슷한 것을 사용합니다

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

파일을 배치했다고 가정합니다 C:\Users\cabbott 내 Windows 시스템에서. Linux 시스템에 액세스 할 수없는 경우 시도하십시오. http://www.cygwin.com/

어쩌면 다른 사람이 다른 Windows 대안을 제안 할 수 있습니다. Putty의 SSH 키를 레지스트리에 저장하여 추출하여 비표준 형식으로 저장하여 추출하여 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");

안전하지 않으며 전 세계적으로 알려진 호스트 키 확인을 비활성화하기 때문에 라이브 환경에 적합하지 않은 해결 방법입니다.

"사용자", "pass", "sshd_ip"을 대체하십시오. 서버의 ~/.ssh/clady_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);
    }
  }
}

이 멍청한 문제에 대해 많은 시간을 잃었고 메시지가 옳다고 생각합니다. "내가 액세스하는 파일에 호스트가 없지만"당신은 당신의 시스템에 know_host 파일 이상을 가질 수 있습니다 (예 : 예를 들어 I '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

그리고 C : Users 아래 내 Windows 집에 있지 않습니다.my_local_user.ssh, 나는 단순히 그것들을 통합하고 문제를 해결하기 위해 정렬했습니다.

이것이 미래에 누군가를 도울 수 있기를 바랍니다

이 문제를 해결할 수있는 사람이 있습니까? 공개 키 인증을 사용하여 JSCP에서 SCP 파일을 사용하고 있습니다 (비밀번호 인증을 사용하고 싶지 않음). 도움이 될 것입니다 !!!

이 stackoverflow 항목은 호스트 키 점검에 관한 것이며 공개 키 인증과 관련이 없습니다.

공개 키 인증에 관해서는 시도해보십시오 다음 샘플 평범한 (암호화되지 않은) 개인 키를 사용하여

알려진 호스트를 설정하는 것이 손가락 인쇄 값을 설정하는 것보다 낫습니다.

알려진 호스트를 설정하면 상자에서 수동으로 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