java - example - com.jcraft.jsch.JSchException: UnknownHostKey
jsch tunnel java (12)
Estoy intentando usar Jsch para establecer una conexión SSH en Java. Mi código produce la siguiente excepción:
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
No puedo encontrar la forma de verificar la clave del host en la documentación de Jsch. He incluido mi código a continuación.
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);
}
}
}
¿Alguien ha sido capaz de resolver este problema? Estoy usando Jscp para scp archivos usando autenticación de clave pública (no quiero usar autenticación de contraseña). ¡Ayuda será apreciada!
Esta entrada de es sobre la comprobación de la clave del host, y no hay relación con la autenticación de la clave pública.
En cuanto a la autenticación de clave pública, pruebe la siguiente muestra con su clave privada simple (no cifrada),
Es un riesgo de seguridad evitar la verificación de claves del host.
JSch usa la interfaz HostKeyRepository y su clase de implementación predeterminada KnownHosts para administrar esto. Puede proporcionar una implementación alternativa que permita claves específicas implementando HostKeyRepository. O puede conservar las claves que desea permitir en un archivo en el formato known_hosts y llamar
jsch.setKnownHosts(knownHostsFileName);
O con un String de clave pública como se muestra a continuación.
String knownHostPublicKey = "mysite.com ecdsa-sha2-nistp256 AAAAE............/3vplY";
jsch.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));
ver Javadoc para más detalles.
Esta sería una solución más segura.
Jsch es de código abierto y puedes descargar la fuente desde here . En la carpeta de ejemplos, busque KnownHosts.java para conocer más detalles.
Perdí mucho tiempo con este estúpido problema, y creo que el mensaje es correcto: "no está el host en el archivo al que estoy accediendo", pero puedes tener más de un archivo know_host en tu sistema (como ejemplo, Estoy usando mobaXterm y lo mantengo dentro del directorio de instalación montando la casa desde esa raíz).
Si está experimentando: está funcionando desde la línea de comandos pero no forma la aplicación, trate de acceder a su servidor remoto con ssh y verifique con la opción verbosa -v qué archivo se utiliza actualmente, como por ejemplo:
ssh -v [email protected]
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 [email protected] [email protected]
debug1: kex: client->server aes128-ctr [email protected] [email protected]
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
como puedes ver, la clave se encontró en:
debug1: Found key in /home/mobaxterm/.ssh/known_hosts:19
y no en mi casa de Windows en C: / Users / my_local_user / .ssh, simplemente los fusioné y alineé para resolver el problema.
Espero que esto ayude a alguien en el futuro
Proporcione la clave de acceso público del host:
String knownHostPublicKey = "mywebsite.com ssh-rsa AAAAB3NzaC1.....XL4Jpmp/";
session.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));
Según el programa que use para ssh, la forma de obtener la clave adecuada puede variar. Putty (popular con Windows) usa su propio formato para las claves ssh. Con la mayoría de las variantes de Linux y BSD que he visto, solo tiene que buscar en ~/.ssh/known_hosts
. Usualmente ssh de una máquina Linux y luego copio este archivo a una máquina con Windows. Luego uso algo similar a
jsch.setKnownHosts("C://Users//cabbott//known_hosts");
Suponiendo que he colocado el archivo en C:/Users/cabbott
en mi máquina con Windows. Si no tiene acceso a una máquina Linux, intente http://www.cygwin.com/
Tal vez alguien más pueda sugerir otra alternativa de Windows. Encuentro la forma en que Putty maneja las claves SSH almacenándolas en el registro en un formato no estándar molesto para extraer.
Si bien la pregunta ha sido respondida en general, descubrí que hay un case en el que incluso la entrada existente de known_hosts no ayuda. Esto sucede cuando un servidor SSH envía huella digital ECDSA y, como resultado, tendrá una entrada como esta:
|1|+HASH=|HASH= ecdsa-sha2-nistp256 FINGERPRINT=
El problema es que JSch prefiere SHA_RSA y, al conectarse, intentará comparar la huella digital SHA-RSA, lo que dará como resultado un error sobre "host desconocido".
Para solucionar esto simplemente ejecuta:
$ ssh-keyscan -H -t rsa example.org >> known_hosts
o Jsch a Jsch prefiera SHA_RSA en lugar de utilizar la configuración local de HostKeyAlgorithms , aunque no parece que estén demasiado eager por corregir sus bugs .
Simplemente sustituya "usuario", "pase", "SSHD_IP". Y cree un archivo llamado known_hosts.txt con el contenido de ~ / .ssh / known_hosts del servidor. Obtendrás un caparazón.
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);
}
}
}
También puede ejecutar el siguiente código. Está probado y funcionando.
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;
}
}
}
Por favor sustituya los valores apropiados.
También puedes simplemente hacer
session.setConfig("StrictHostKeyChecking", "no");
No es seguro y es una solución alternativa que no es adecuada para el entorno en vivo, ya que desactivará la comprobación de claves de host conocidas mundialmente.
Yo también:
- Intente
ssh
desde la línea de comando y acepte la clave pública (el host se agregará a~/.ssh/known_hosts
y todo debería funcionar bien desde Jsch) -O- Configure JSch para que no use "StrictHostKeyChecking" (esto introduce inseguridades y solo debe usarse para realizar pruebas), usando el siguiente código:
java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config);
La opción n. ° 1 (agregar el host al archivo ~/.ssh/known_hosts
) tiene mi preferencia.
configurar el host conocido es mejor que configurar el valor de impresión fingure.
Cuando configure el host conocido, intente hacerlo manualmente (la primera vez, antes de que la aplicación se ejecute) desde el cuadro en el que se ejecuta la aplicación.
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");
}
}