洗澡时,我终于跑出来喊出了我的 Eureka

2018-12-14 13:10:06 +08:00
 ChristopherWu

来自我的公众号『 YongHao 写东西的 Cache 』 打个小广告,还是希望写的东西有人看🙊

洗澡时,我终于跑出来喊出了我的 Eureka

今天与一位帅气的同事一起解决了一下 ssh 的相关问题,在我装逼的提及不需要显式指定 identity key 的时候,顺道提及 known_hosts 也是一样的时候,说到了known_hosts的现象:

但是原理被含糊不清的略过去了———至少没有刻意提到,因为我是不大懂的。

在今晚洗澡时,回想了一下今天的事情,想到了这件事情,不禁尝试想清楚 kown_host 是啥东西,为什么需要它。

前几天看到知乎上,有一篇文章介绍了拉马努金自己尝试推导一切未知但已成结论的数学公式,作者学习此方法自己尝试推导出机器学习的论文。

不知道是不是潜意识的影响(我在那时肯定没想到这篇文章),我在结合以上已知 known_host 的两点现象,以及以前零散的 ssh 原理知识,尝试推导 ssh 为什么运作的。

RSA 的原理无需累述,就用我以前总结过的为介绍吧:

RSA 是非对称加密算法, 对称算法就是双方用同一个密钥加密。RSA 是基于对两个质数相乘容易,而将其合数 分解很难的这个特点进行的加密算法 生成公钥与私钥, 公钥加密而私钥解密, 或者相反都可以。 一般公钥公开到网上, 想发送信息给你的人用公钥加密, 而只有你拥有私钥可以解密, 这样确保了信息的保密。 或者你用私钥加密, 其他所有人都可以用公钥解密你的信息, 这样可以确保信息是由你所发出。 网上发邮件或者个人网站上所用到的签名, 就是使用此技术。

而 SSH 就是利用了这个原理,你可以从此方面尝试去推导出你如何做一个 ssh。

而我推导出的过程是这样的:

目的就是 server 要识别 client 就是 authorize_keys 里记录的 client

  1. 在 server 上的authorize_keys里添加 client 的公钥了(这步大家都知道)

  2. client 发起 ssh 连接到 server,发送公钥给 server

  3. server 用 client 发送的公钥对比 authorize_keys里的记录是否一致,认证 client 是否有权限

  4. 此时 server 发送一个字符串(如"generated by server")发送给 client,目的就是 client 用私钥加密后,发回去后,server 可以解密,与记录的字符串对比一致

  5. 此时可以确认 client 就是authorize_keys 里记录的 client 了

以上一切完成。

为什么需要known_host呢? 上述过程有一个问题就是,无法抵御中间人攻击。

假如在你以后链接 server 时,被中间人攻击了,中间人模仿 server 的行为与你进行 ssh 校验,你就会连上去,并且难以发现。

因此显然易见的一个方法就是,在第一次建立连接成功后,在一个文件里记录 IP,公钥这样的键值对,以后连接时对比一下与第一次连接的公钥是否一致即可。 而这个文件就被 ssh 命名为 known_hosts ,因此不一致时,拒绝了你的 ssh 连接,并且提示 中间人攻击。

那么保证第一次连接是对的话,就只有人工去对比了。 服务器自己公开公钥信息了,客户端自己去对比。


对比结果

事后对比,以上的做法是对的,只是没那么严谨。

有以下几个细节是不同的:

  1. 客户端应该是需要发送公钥到服务器的,目前没有看到有说明这个的地方,需要再查
  2. 发送的固定字符串,不是用明文,而是用客户端的公钥加密了
  3. 服务器发给客户端去做私钥加密时,生成的不是固定的字符串,而是随机字符串(这个是细节没有打磨,因为发送固定字符串,明显客户端私钥加密过的东西是固定的,就无法保密了)
  4. 最后对比这个随机字符串时,还用了SessionKey来做 md5,还没细查

感想

以上的文章,技术细节不怎么重要,重要的是背后的一些大家都知道道理:

对一切保持好奇心,尽量探寻其中的原理,这才对得住计算机科学。赫歇尔对好奇七色光实验为何会有额外的温度变化才发现不可见光(红外线,紫外线呢),法拉第不懈尝试各种材料才发现玻璃能帮助磁场让光改变路径,证实磁场与光有关联。 计算机也是基于黑盒上完整的生态圈,如 HTTP,TCP,CPU,PL 等,同样可以对他们保持好奇心,与用拉马努金的方法来推导构建此黑盒,与自己的对比,想必大有裨益。

花絮

Why Eurekai ? Eureka – (希腊语:εὕρηκα;拉丁化:Eureka ;词义:“我发现了!”)

阿基米德在洗澡时发现浮力原理,高兴得来不及穿上裤子,跑到街上大喊:“Eureka!”

古希腊学者阿基米德 (Archimedes),有一天,他在洗澡的时候发现,当他坐进浴盆里时有许多水溢出来,这使得他想到:溢出来的水的体积正好应该等于他身体的体积,这意味着,不规则物体的体积可以精确的被计算,这为他解决了一个棘手的问题。阿基米德想到这里,不禁高兴的从浴盆跳了出来,光着身体在城里边跑边喊叫着 “尤里卡!尤里卡!”,试图与城里的民众分享他的喜悦。

So.. Eureka! Eureka!

在自己设计想清楚了 SSH 之后,我在寒冬不禁高兴的从浴室跳了出来,光着身体在客厅边跑边喊叫着 “ Molly,Molly ”, 跟女票论述了我此番的感想。

因为她对 ssh 原理心中一直有根刺,也很感兴趣,让我把 ssh 以及 RSA 的原理都给她说了一遍,草稿如下:


3,5,7,11,13,17。。。

191 (13,17)

公钥 《=》私钥

公钥暴露,别人无法暴力破解对比出私钥

=》私钥永远不能暴露,不能发送出去,只能放自己机器。

公钥 私钥

公钥放 GitHub 服务器

molly ssh 到 GitHub =》 molly 发起 ssh 链接 -》 发公钥给 GitHub -》 GitHub 就可以跟你放 GitHub 服务器的公钥做对比,校验你有没有权限 -》“随机生成的字符串” 发给 molly -》 molly 用私钥来加密随机生成的字符串 ,发给 GitHub -》 GitHub 用 molly 的公钥来解开这个内容,对比是否刚刚发给 molly 的随机字符串 =》一切都通了。

中间人 =》 你要想像中间随便有一个人可以监听你的网络

molly -- chalres -- github

  1. SSL
  2. ~/.ssh/known_hosts
8347 次点击
所在节点    程序员
64 条回复
forcecharlie
2018-12-15 17:36:28 +08:00
我有个不成熟的建议,ssh -Tvvv 可以看流程。
msg7086
2018-12-16 04:48:56 +08:00
@p1gd0g 拿 RSA 举例,公钥是 n&e,私钥是 n&d,可以通过 n 和 d 推导出 e 的值吗?
反正我是想不出在没有公钥那一半数据的情况下私钥如何去「推导」出公钥的那一半。
p1gd0g
2018-12-16 09:17:10 +08:00
@msg7086 俺明白自己为啥懵逼啦,看啦两年的论文全是基于离散对数问题,而 RSA 是基于整数分解问题。
在 RSA 中 e * d = 1 mod \lambda(n),在已知 \lambda(n) 的情况下是可以对公私钥相互转换的,但是 \lambda(n) 不可以公开。在这种情况下,密钥生成和分发会引发一些安全性问题,这可能也是基于整数分解问题的研究越来越少的原因吧。

感谢指正。
msg7086
2018-12-16 09:52:12 +08:00
@p1gd0g 像 RSA 这样的算法,只要保存有足够的原始参数信息,就相当于把私钥和公钥一起保存下来了。
如果只拥有「私钥」部分,是无法推出「公钥」部分的,所以我才说实际应用中相当于把公钥和私钥一起存了。
其他的算法我也不太清楚,毕竟我不是学密码学出身的,只能说略知皮毛了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/517517

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX