图解SSH登录过程
前言
SSH是为远程登录和其他网络服务器提供安全性的协议,是目前使用较广泛且比较可靠的协议。本文会通过画图的方式形象地介绍SSH登录过程,看完这篇文章你将了解到:
- SSH所使用到的几种数据加密、处理方法
- SSH登录的过程中都做了什么
- SSH是如何确保安全通信的
想要更加详细地了解,可以参考这篇文章
数据加密、处理
SSH为了确保安全性,在会话建立和整个会话过程中使用了几种数据加密、处理的方式。包括:对称加密、非对称加密和密钥哈希函数。下面将会简单介绍
对称加密
对称加密是指加密和解密都通过同一个密钥进行;或者是使用一个密钥对,其中一个用于加密而另一个用于解密,但这两个密钥间的关系是比较容易就能推导出来的,即通过其中一个可以推导出另一个(其实本质上还是一个密钥)。 假设A和B使用对称加密进行通信(使用同一个密钥),A给B发送信息:

上图对称加密的过程可以这样描述:
- A给B发送信息前,先使用密钥加密明文
- A将密文发送给B
- B收到密文,使用相同的密钥进行解密,获得A中的明文。
反过来B给A发信息也是一样的
非对称加密
非对称加密使用一个密钥对进行加密和解密。这个密钥对中一个称作公钥,另一个称作私钥。公钥只负责对信息进行加密,私钥只负责对信息进行解密,最重要的是,私钥是无法从公钥推导出来的。
同样我们假设A和B使用非对称加密进行通信,A给B发送信息:

上图的过程是这样的,B有一个密钥对(公钥和私钥):
- 首先,无论通过什么方式,B都要先将他的公钥分享给A。
- A使用B的公钥对明文进行加密。
- A将密文发送给B。
- B收到密文,使用自己的私钥对信息进行解密,得到A的明文。
反过来,若B要给A发送信息,那么B也必须知道A的公钥。
密文哈希算法
要注意的是,密文哈希算法并不是一种加密算法。哈希算法对于数据的处理是单向的,即明文到密文的过程不可逆,无法从哈希算法得到的结果去获得原来的信息。同时,哈希算法可以把任意长度的信息处理成固定长度的结果。此外,相同明文进行哈希算法得到的结果永远是相通的,而不同明文几乎不可能得到相同的结果(理想状态的话是完全不可能得到。)
Diffie-Hellman算法
Diffie-Hellman算法是一种密钥交换算法,用于生成密钥和通信双方交换共享密钥(用于对称加密的密钥),他可以保证通信的双方一起参与到共享密钥的生成过程,而且确保密钥在交换过程中的安全性,即使第三方窃听了通信信息,也无法获得共享密钥。 一般Diffie-Hellman算法的步骤如下:
- 双方商定一个较大的素数作为种子值。
- 双方商定一种加密方式(一般为AES),用于处理数据。

- 双方独自生成另外一个素数,且不能让另一方知道。这个素数可以说是交互过程中的私钥。

- 双方使用各自的私有素数(私钥)、以及共享的素数(种子值),通过商定的加密方式产生公钥,此公钥是可以公开给另一方的。
- 双方交换他们生成的公钥。

- 收到公钥后,使用自己的私钥,对方的公钥以及共享的素数(种子值)计算出共享密钥,尽管这个共享密钥是通过对方的私钥和公钥计算出来的,但双方最后都会获得相同的共享密钥。

SSH登录过程
SSH的登录主要分为了两个阶段:(1)协商好客户端和服务器双方通信所使用的共享密钥,用这个共享密钥实现后续会话全过程的对称加密。(2)使用非对称加密方式验证客户端的身份。
协商会话所使用的共享密钥
这是SSH会话建立的第一个阶段,在这个阶段中主要使用到了Diffie-Hellman算法。 下图是客户端(A)与服务器(B)建立会话的过程:

- 客户端发起TCP连接。
- 服务器会返回其支持的协议版本以及服务器的公共主机密钥,公共主机密钥用于判断服务器是否预期的主机。
- 双方通过Diffie-Hellman算法交换一个会话密钥。
- 双方获得共享密钥,用于为后续会话做对称加密。
验证用户对服务器的访问权限
在协商好会话使用的共享密钥后,将进行用户验证。有两种方法可以用于验证用户身份:
- 密码认证
- SSH密钥对
密码认证
使用密码认证时,服务器会想客户端请求登录账户的密码,这个密码会经过对称加密。
SSH密码认证的步骤如下:

- 服务器收到客户端请求后,把自己的公钥发送给客户端(这跟SSH密钥对不同,是服务器自身的公钥/私钥对)。
- 客户端使用收到的公钥加密密码,并发送回服务器。
- 服务器使用自己私钥解密信息,若密码正确,则通过验证。
SSH密钥对验证
密码验证的安全性并不算好,推荐使用SSH密钥对验证。使用密钥对验证前,要先将客户端的SSH密钥对的公钥填到服务器对应账户的authorized_keys文件中。
SSH密钥对验证的步骤如下:

- 客户端把他用于验证的SSH密钥对的ID发送给服务器
- 服务器根据密钥对ID在对应用户的
authorized_keys文件中进行检索 - 假设服务器在文件找到了符合密钥对ID的公钥,服务器将生成一个随机数,并用这个公钥进行加密。
- 服务器将加密后的信息发送给客户端
- 假设客户端拥有对应的私钥,那他就可以从加密信息中解密出原来的随机数。
- 客户端将得到的随机数与加密会话所使用的会话密钥间拼接在一起后,计算出其MD5哈希值。
- 客户端把MD5哈希值发送回服务器。
- 服务器自己使用相同的会话共享密钥和他生成的随机数计算出MD5值,把它和客户端返回的MD5值进行比较。如果两个值相等,则证明客户端拥有对应私钥,将通过验证。
总结
以上就是SSH登录的过程,如需要更详细的信息,可以查阅Secure Shell的wiki。如有错误,欢迎指出~~