即使服务器的主机密钥存在于 known_hosts 文件中,JSch 连接也会因 UnknownHostKey 失败

如何解决即使服务器的主机密钥存在于 known_hosts 文件中,JSch 连接也会因 UnknownHostKey 失败

我正在使用 JSch 在多个 VPS 上部署各种文件。我能够在关闭 StrictHostKeyChecking 的情况下获得一个工作原型。我现在想重新启用主机密钥检查,这样我就不容易受到 MITM 攻击。目前,客户端是连接到运行 Debian 的 VPS 的 Windows 机器。这是我到目前为止所做的:

  1. 使用 "ssh-keyscan -t rsa <serverIp> >> ~/.ssh/known_hosts" 在我的本地机器(Windows 客户端)上添加远程 IP 地址
  2. 将我的 known_hosts 文件的路径传递给我的应用程序中的 JSch.setKnownHosts

尝试建立连接时,结果是

com.jcraft.jsch.JSchException: UnknownHostKey: 。 RSA 密钥指纹是

这显然是由于我对主机密钥的工作原理或与此相关的密码学缺乏了解。根据我的基本理解,known_hosts 文件包含一个密钥。该密钥用于确保我们连接到的远程 IP 是他们所说的人,从而防止任何人试图“欺骗”自己作为服务器。

我的 known_hosts 文件看起来像

184.154.70.174 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNv4m+tOZUipp8UDGrd+kbtsM5R+tu3ZYZi3p7OTRWUX/Wqy74pONlLqI+/WGu77EHnOfdssJfclgo37vKLRFKneXZNAMXE7FUu5yUNOHlpPwzmvYUT/sp1k9CeNrtJAbkm05pOBIDqDQQGfQ+IAw9zqqo/sqJ6c8NKiVFAt4Ud0msvedb559dhYgcjwb52ABbsJ0mZ8FnU7LKG1592/ZTtYxam+M3qMhtJacrh5gpfZjjx2lGhqpOgvM+xwWeK6DQVn0QyIJd474G3gcm4M43ErRfzXOum3p/0wOw+hL1ora9eWSz2Wf9WuDXf86xkbZPD7Gy6ER5LBhquy331p7X

我的代码是(SSH 是 JSch 的一个实例):

try {
    SSH.setKnownHosts(new FileInputStream("C:/Users/nvulc/.ssh/known_hosts"));
    SSH.addIdentity(keyPath,keyPass);
    Session session = SSH.getSession("root","184.154.70.174",22);
    session.connect();
} catch (Exception e) {
    e.printStackTrace();
}

结果:

    com.jcraft.jsch.JSchException: UnknownHostKey: 184.154.70.174. RSA key fingerprint is b4:79:5a:58:d3:15:ad:a9:c7:af:cc:d7:09:f5:40:62
    at com.jcraft.jsch.Session.checkHost(Session.java:805)
    at com.jcraft.jsch.Session.connect(Session.java:345)
    at com.jcraft.jsch.Session.connect(Session.java:183)
    at Main.main(Main.java:40)

解决方法

您的方法是正确的,如果操作正确,应该会起作用。尽管仅供参考,它并不能完全防止 MitM -- ssh-keyscan 本身使用未经验证的连接并且容易受到 MitM 的攻击,尽管如果该连接是合法的,但检查密钥可以防止伪造 稍后 连接。这是 SSH 常见的“ToFU”(首次使用信任)安全模型的一种形式/变体。

根据我的基本理解,known_hosts 文件包含一个密钥。 ...

通常,known_hosts 包含从主机身份(名称和/或 IP 地址)到密钥的映射。但是,如果您的文件只是按照您显示的方式创建的,那么它只有一个包含一个键的映射条目。

  1. 确保您将正确的路径传递给 setKnownHosts以正确的(相同)用户身份运行。如果您指定的路径无法打开(不存在或不允许访问),Jsch 不会抛出任何错误,它只会返回而不加载任何内容。您可以改为自己使用 new FileInputStream(pathstring) 打开文件并传递给 setKnownHosts(InputStream) 重载,因此如果打开失败,您会收到异常。

  2. 确保您使用相同的主机身份。如果例如一个主机有多个名称(就像云服务器经常做的那样),您在 ssh-keyscan 中使用一个,但在 JSch 中使用一个不同的名称,那么即使这实际上是相同的主机和密钥,它也不会匹配。但是,如果您实际上在两个地方都使用 IP 地址,至少如果您指的是 IPv4,则这种情况不太可能发生,因为当今很少有机器拥有多个公共 IPv4 地址。 (在过去,这更常见,称为多宿主。)IPv6 更有可能;大多数 IPv6 机器都有临时和永久公共地址(以及本地/私有地址),而且通常有多个临时地址。

,

你的代码对我有用 - https://www.browxy.com/#ALIEN_137442 - 它以 "JSchException: Auth fail" 结尾 - 这意味着它通过了主机密钥验证。

确保 known_hosts 文件是纯 ASCII 编码(或 UTF-8 没有 BOM,对于此类内容,它应该与 ASCII 相同)。但不是 UTF-8 with BOM,只让 UTF-16 或更糟。

也试试 Unix 行尾。虽然行尾应该不是问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-