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

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

我是 运行 一个 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.

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

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

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

旁白:"Cygwin" 我假设你指的是 sshd 或 sftpd,因为 Cygwin 本身不支持 SSH。

无论如何,如果您希望 Jsch 客户端接受来自主机的任何密钥,请移动设置 StrictHostKeyChecking no.setConfig 调用,使其在 之前 session.connect()。或者,您必须像@Martin 解释的那样,为您的主机提供对包含正确密钥的商店的访问权限——并且在连接到 "localhost" 以外的任何东西或可能是特定的机器时,您应该始终这样做位于同一物理安全网段(例如单个房间内的有线 LAN 集线器)。

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

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


无论如何,你不应该这样做,除非你不关心安全。主机密钥检查可以保护您免受 man-in-the-middle attacks.

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

例如:

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

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

    ssh-keyscan example.com > known_hosts
    

    它的格式如下:

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

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

    如果您在 Windows,您可以从 Win32-OpenSSH project 或 Git 获得 Windows 的 ssh-keyscan 版本 Windows。

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

    参见

jsch 版本:0.1.55

我的问题被 运行 解决了:

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

**在我的例子中,jsch 在 known_hosts 文件

中寻找 IP 地址
jsch.setKnownHosts(System.getProperty("user.home")+"/.ssh/known_hosts");