浅谈SSH2工作原理
最近在研究 GitHub 多账号管理 的问题,这其中就涉及到了 SSH 的连接方式,因此不得不了解一下 SSH 的工作原理。
一番搜索和实践后发现,这里面的水其实很深,真要理解透彻可能需要去读几本关于密码学的书。本人并没有多大兴趣去研究这个,所以只是浅谈,但对于只是使用 SSH 工具的人来说,这完全够用了。
几年前我了解到的是 SSH 使用非对称加密算法(RSA)来完成对称加密算法的密钥交换,最后使用对称加密算法实现数据安全传输。现在网上查到的却是先使用 Diffie-Hellman(DH)算法完成对称加密算法的密钥交换,再通过客户端的公钥识别身份。这让我丈二和尚摸不着头脑。
直到写这篇文章,在搜索了 SSH1 和 SSH2 的区别后,我才找到答案。原来这里面说的其实是两个不同的东西,一个是 SSH1,一个是 SSH2。现在都流行使用 SSH2,所以网上搜到的大多都是 SSH2 方面的东西。
如果你直接在网上搜索 “ SSH 实现原理 ”,那么搜到的大多都只是在谈 SSH 的身份认证部分而非整一个工作原理。试着搜索 “ SSH 协商会话加密 ”,你将会看到不一样的内容。
SSH2 的整一个连接过程大体上可分为两个部分: 协商会话加密 和 身份认证 。
这其中还用到了 对称加密 、 非对称加密 和 哈希 算法( MD5 )。
协商会话加密 使用 Diffie-Hellman 算法生成会话密钥,具体流程如下。(大概流程)
注意这里的公钥、私钥和下面要讲的非对称加密的公钥、私钥是不一样的,不是同一个东西。
共享密钥 确定后,接下来的通信都使用 共享密钥 进行加密和解密,因此是安全的,但我们还没有确认双方的身份。
客户端识别服务端是通过人工进行确认的。我们在第一次连接服务器时,都会弹出一个警告,让用户确定是否进行连接。警告的内容包含了服务器的 公钥指纹 ,如下图。
既然 公钥 是公开的,那中间人是不是也可以伪造这样的信息,让我们误以为是真实的服务器发出来的?答案是“是的”,所以我们还需要确定服务端是否拥有对应的私钥。不过查阅相关的文章,好像没有这样一个过程,都是在用户确定服务端公钥(回复yes)后就进行下一步操作(确认客户端身份)。个人感觉不合理,应该是要有的,具体我也没有深究,毕竟这篇文章是 浅谈 嘛!(好像被发现为什么要用这个做标题了😁。)
其实要确定服务端是否拥有对应的私钥也很容易,接下来讲的如何确定客户端身份会讲到,道理是一样。
服务端识别客户端身份有两种方式: 账号密码 和 SSH密钥对 。
账号密码 验证的方式很容易理解,客户端将用户名和密码用 共享密钥 加密后发给服务端,服务端再使用 共享密钥 解密,取得用户名和密码,再以此验证用户信息。
SSH密钥对 需要管理员事先将客户端的公钥上传到服务端对应用户的 ~/.ssh/authorized_keys 文件中,再进行以下流程。
前面说到在 协商会话加密 后,以后的通信都会使用 共享密钥 进行加密。在使用 SSH密钥对 进行 身份认证中 ,是可以不使用 共享密钥 进行加密的,因为整个过程所用到的 加密随机数 和 MD5值 是可以公开的。具体在真实的场景中有没有使用 共享密钥 ** 加密这个过程我也不太清楚( 浅谈浅谈**),不过不会有什么安全问题。
到这里,整个通信流程大家应该都理解了,不过我猜大家还会有一些问题。
一开始我以为是为了连接速度,后来查了 SSH1 和 SSH2 的区别才发现,问题并不简单。
下面引用 海里木有鱼 的 SSH1和SSH2的区别 内容来解答这个问题。
一切,都是利益的纠葛!
ssh-agent 自动寻找,或者 ssh 登录时指定私钥(公钥和私钥名相同)。详细内容可以看 SSH多种远程登录方法
由于这个种子值是可以公开的,所以不怕被第三方知道。可以由客户端或者服务端自己随机生成然后发给对方,只要对方同意就行了。就像两个人去吃饭,讨论要选择哪个餐馆是一样的道理。
Understanding the SSH Encryption and Connection Process ,Justin Ellingwood
SSH 加密和连接过程 ,WqyJh
SSH1和SSH2的区别 ,海里木有鱼