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);
}
}
}
답변
나도 :
- 하려고
ssh
명령 줄에서 공개 키를 받아 (호스트가 추가됩니다~/.ssh/known_hosts
모든 것을해야 Jsch에서 다음 작업 벌금) – 또는 – -
다음 코드를 사용하여 “StrictHostKeyChecking”을 사용하지 않도록 JSch를 구성하십시오 (이로 인해 보안 문제가 발생하고 테스트 목적으로 만 사용해야 함).
java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config);
옵션 # 1 (호스트를 ~/.ssh/known_hosts
파일에 추가 )이 선호됩니다.
답변
이 질문은 일반적으로 답변되었지만 기존 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 에 불만을 제기 하지만 버그 를 수정 하기에는 너무 열망 하지는 않습니다 .
답변
호스트 키 검사를 피하는 것은 보안 위험입니다.
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를 찾아 자세한 내용을 확인하십시오.
답변
ssh에 사용하는 프로그램에 따라 적절한 키를 얻는 방법이 다를 수 있습니다. 퍼티 (Windows에서 인기)는 ssh 키에 대해 자체 형식을 사용합니다. 내가 본 Linux와 BSD의 대부분의 변종은에서 찾아보아야한다 ~/.ssh/known_hosts
. 나는 보통 리눅스 머신에서 ssh를 한 다음이 파일을 윈도우 머신으로 복사한다. 그런 다음 비슷한 것을 사용합니다.
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()));
답변
간단하게 할 수도 있습니다
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;
}
}
}
적절한 값으로 대체하십시오.