使用 JSch SFTP 库时如何解析 Java UnknownHostKey?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32852906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 13:12:53  来源:igfitidea点击:

How to resolve Java UnknownHostKey, while using JSch SFTP library?

javasshsftpjschpublic-key

提问by Coffee

I'm running a java program where I transfer a file from one folder to another, using Java SFTP. The problem I'm having is that I'm getting the following error in my Java SFTP (using JSch) :

我正在运行一个 java 程序,我使用 Java SFTP 将文件从一个文件夹传输到另一个文件夹。我遇到的问题是我的 Java SFTP(使用 JSch)出现以下错误:

C:\Oracle\Middleware\Oracle_Home\oracle_common\jdk\bin\javaw.exe -server -classpath C:\JDeveloper\mywork\Java_Hello_World.adf;C:\JDeveloper\mywork\Java_Hello_World\Client\classes;C:\Users\ADMIN\Downloads\jsch-0.1.53.jar -Djavax.net.ssl.trustStore=C:\Users\IBM_AD~1\AppData\Local\Temp\trustStore5840796204189742395.jks FileTransfer com.jcraft.jsch.JSchException: UnknownHostKey: 127.0.0.1. RSA key fingerprint is a2:39:3f:44:88:e9:1f:d7:d1:71:f4:85:98:fb:90:dc at com.jcraft.jsch.Session.checkHost(Session.java:797) at com.jcraft.jsch.Session.connect(Session.java:342) at com.jcraft.jsch.Session.connect(Session.java:183) at FileTransfer.main(FileTransfer.java:33) Process exited with exit code 0.

C:\Oracle\Middleware\Oracle_Home\oracle_common\jdk\bin\javaw.exe -server -classpath C:\JDeveloper\mywork\Java_Hello_World.adf;C:\JDeveloper\mywork\Java_Hello_World\Client\classes;C:\Users \ADMIN\Downloads\jsch-0.1.53.jar -Djavax.net.ssl.trustStore=C:\Users\IBM_AD~1\AppData\Local\Temp\trustStore5840796204189742395.jks FileTransfer com.jcraft.jsch.JSchException: UnknownHostKey: 127.0.0.1。RSA 密钥指纹是 com.jcraft.jsch.Session.checkHost(Session.java: 797) 在 com.jcraft.jsch.Session.connect(Session.java:342) 在 com.jcraft.jsch.Session.connect(Session.java:183) 在 FileTransfer.main(FileTransfer.java:33)退出代码 0。

The following is my code so far:

以下是我到目前为止的代码:

FileTransfer fileTransfer = new FileTransfer();              

JSch jsch = new JSch();

try {

    String host = "127.0.0.1";
    int port = 22;

    String user = "user";
    Session session = jsch.getSession(user, host, port);      
    session = jsch.getSession("username", "127.0.0.1", 22);
    session.connect();  // bug here , java.net.ConnectException

    ChannelSftp sftp = null;
    sftp = (ChannelSftp)session.openChannel("sftp") ; //channel;

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

    sftp.rename("C:\Users\ADMIN\Desktop\Work\ConnectOne_Bancorp\Java_Work\SFTP_1\house.bmp", "C:\Users\ADMIN\Desktop\Work\ConnectOne_Bancorp\Java_Work\SFTP_2\house.bmp");  
    session.disconnect();

} catch (JSchException e) {
    e.printStackTrace();  
} catch (SftpException e) {
    e.printStackTrace();
} //end-catch

My Cygwin is set up, and I checked (with netstat -a -b) that it's running.

我的 Cygwin 已设置,我检查(使用netstat -a -b)它正在运行。

采纳答案by Martin Prikryl

You are trying to skip a host key checking by setting StrictHostKeyCheckingto no.

您试图通过设置StrictHostKeyChecking为来跳过主机密钥检查no

But you have to do that before the checking, i.e. before the session.connect().

但是你必须在检查之前这样做,即在session.connect().



Anyway, you should never do this, unless you do not care about security. The host key checking is there to protect you from man-in-the-middle attacks.

无论如何,您永远不应该这样做,除非您不关心安全性。主机密钥检查是为了保护您免受中间人攻击

Instead, set up an expected host key to let JSch verify it.

相反,设置一个预期的主机密钥让 JSch 验证它。

For example:

例如:

  • Call JSch.setKnownHostsproviding a path to a .ssh/known_hosts-like file.

    To generate the .ssh/known_hosts-like file, you can use an ssh-keyscancommand from OpenSSH. If you are connecting from a *nix server, you should have the command available, just run

    ssh-keyscan example.com > known_hosts
    

    It will have a format like:

    example.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0hVqZOvZ7yWgie9OHdTORJVI5fJJoH1yEGamAd5G3werH0z7e9ybtq1mGUeRkJtea7bzru0ISR0EZ9HIONoGYrDmI7S+BiwpDBUKjva4mAsvzzvsy6Ogy/apkxm6Kbcml8u4wjxaOw3NKzKqeBvR3pc+nQVA+SJUZq8D2XBRd4EDUFXeLzwqwen9G7gSLGB1hJkSuRtGRfOHbLUuCKNR8RV82i3JvlSnAwb3MwN0m3WGdlJA8J+5YAg4e6JgSKrsCObZK7W1R6iuyuH1zA+dtAHyDyYVHB4FnYZPL0hgz2PSb9c+iDEiFcT/lT4/dQ+kRW6DYn66lS8peS8zCJ9CSQ==
    

    And reference the generated known_hostsfile in your JSch code.

    If you are on Windows, you can get a Windows build of ssh-keyscanfrom Win32-OpenSSH projector Git for Windows.

  • Call JSch.getHostKeyRepository().add()to provide the expected host key (e.g. hard-coded, as your other credentials).

    See Creating JSch HostKey instance from a public key in .pub format.

  • 调用JSch.setKnownHosts提供一个类似.ssh/known_hosts文件的路径。

    要生成.ssh/known_hosts类似文件,您可以使用ssh-keyscan来自 OpenSSH的命令。如果您从 *nix 服务器连接,您应该有可用的命令,只需运行

    ssh-keyscan example.com > known_hosts
    

    它将具有如下格式:

    example.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0hVqZOvZ7yWgie9OHdTORJVI5fJJoH1yEGamAd5G3werH0z7e9ybtq1mGUeRkJtea7bzru0ISR0EZ9HIONoGYrDmI7S+BiwpDBUKjva4mAsvzzvsy6Ogy/apkxm6Kbcml8u4wjxaOw3NKzKqeBvR3pc+nQVA+SJUZq8D2XBRd4EDUFXeLzwqwen9G7gSLGB1hJkSuRtGRfOHbLUuCKNR8RV82i3JvlSnAwb3MwN0m3WGdlJA8J+5YAg4e6JgSKrsCObZK7W1R6iuyuH1zA+dtAHyDyYVHB4FnYZPL0hgz2PSb9c+iDEiFcT/lT4/dQ+kRW6DYn66lS8peS8zCJ9CSQ==
    

    known_hosts在您的 JSch 代码中引用生成的文件。

    如果您使用的是 Windows,则可以ssh-keyscanWin32-OpenSSH 项目或 Git for Windows 获取 Windows 版本。

  • 调用JSch.getHostKeyRepository().add()以提供预期的主机密钥(例如,硬编码,作为您的其他凭据)。

    请参阅从 .pub 格式的公钥创建 JSch HostKey 实例

回答by dave_thompson_085

Aside: by "Cygwin" I assume you mean sshd or sftpd, because Cygwin itself doesn't do SSH.

旁白:我认为“Cygwin”是指 sshd 或 sftpd,因为 Cygwin 本身不支持 SSH。

Anyway, if you want Jsch client to accept any key from the host, move the .setConfigcalls that sets StrictHostKeyChecking noso it is beforesession.connect(). Alternatively you must provide access to a store containing the correct key(s) for your hosts(s) as @Martin explains -- and you should always do that when connecting to anything other than "localhost" or possibly a machine certain to be on the same, physically-secure network segment (such as a wired LAN hub within a single room).

无论如何,如果你想Jsch客户端接受来自主机的任意键,移动.setConfig电话,设置StrictHostKeyChecking no所以它是session.connect()。或者,您必须提供对包含主机正确密钥的存储的访问权限,正如@Martin 所解释的那样——并且在连接到除“localhost”以外的任何内容或可能是某台机器时,您应该始终这样做相同的物理安全网段(例如单个房间内的有线 LAN 集线器)。

回答by swaz

jsch version : 0.1.55

jsch 版本:0.1.55

my problem solved by running :

我的问题通过运行解决了:

ssh-keyscan -t rsa <HOST_NAME> >> ~/.ssh/known_hosts
ssh-keyscan -t rsa <IP_ADDRESS_OF_HOST_NAME> >> ~/.ssh/known_hosts

**in my case jsch was looking for ip address in known_hosts file

**在我的例子中,jsch 在 known_hosts 文件中寻找 IP 地址

jsch.setKnownHosts(System.getProperty("user.home")+"/.ssh/known_hosts");