如何在使用 JSch SFTP 库时解决 Java UnknownHostKey?
Posted
技术标签:
【中文标题】如何在使用 JSch SFTP 库时解决 Java UnknownHostKey?【英文标题】:How to resolve Java UnknownHostKey, while using JSch SFTP library? 【发布时间】:2015-12-27 11:03:48 【问题描述】:我正在运行一个 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 密钥指纹是 a2:39:3f:44:88:e9:1f:d7:d1:71:f4:85:98:fb:90:dc 在 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.
以下是我目前的代码:
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
)它正在运行。
【问题讨论】:
【参考方案1】: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");
【讨论】:
使用正确的主机密钥附加 ~/.ssh/known_host 文件解决了问题,感谢前两行评论! Jsch 不会附加文件,您必须手动执行。就是这样!【参考方案2】:您正试图通过将StrictHostKeyChecking
设置为no
来跳过主机密钥检查。
但你必须在检查之前这样做,即在session.connect()
之前。
无论如何,除非您不关心安全性,否则您永远不应该这样做。主机密钥检查可以保护您免受man-in-the-middle attacks 的侵害。
相反,设置一个预期的主机密钥让 JSch 验证它。
例如:
调用JSch.setKnownHosts
,提供.ssh/known_hosts
-like 文件的路径。
要生成类似.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 或适用于 Windows 的 Git 获得 ssh-keyscan
的 Windows 版本。
调用 JSch.getHostKeyRepository().add()
以提供预期的主机密钥(例如硬编码,作为您的其他凭据)。
见Creating JSch HostKey instance from a public key in .pub format。
【讨论】:
【参考方案3】:除此之外:“Cygwin”我假设您的意思是 sshd 或 sftpd,因为 Cygwin 本身不执行 SSH。
无论如何,如果您希望 Jsch 客户端接受来自主机的任何密钥,请移动设置 StrictHostKeyChecking no
的 .setConfig
调用,使其位于 之前 session.connect()
。或者,您必须提供对包含主机正确密钥的存储的访问权限,正如@Martin 解释的那样——并且在连接到“localhost”以外的任何东西或可能肯定在的机器时,您应该始终这样做相同的、物理安全的网段(例如单个房间内的有线 LAN 集线器)。
【讨论】:
“你必须”:请不要建议任何人不要验证 SSH 主机密钥。至少不是不解释后果。这是一个可怕的安全错误。 顺便问一下什么是sftpd? @Coffee 我的意思是“任何专门实现 sftp 的服务器(在 Unix 中通常是一些东西-d),但不是 ssh 的其余部分”。对于 Linux,通常(不总是)vsftpd,但我不知道 cygwin。我可能应该说“一个 sftp 服务器”。 @dave_thompson_085 对于 Linux,它是 OpenSSH,而不是 vsftpd。 Cygwin 也是如此。以上是关于如何在使用 JSch SFTP 库时解决 Java UnknownHostKey?的主要内容,如果未能解决你的问题,请参考以下文章