一、对称加密和非对称加密
为了理解SSH,先要介绍两个重要概念:对称加密和非对称加密。
1-1、对称加密
所谓对称加密,指加密解密使用同一套秘钥。如下图所示:
图片.png在对称加密中,客户端和服务端使用同一个密钥对数据进行加密和解密。这种方法的好处是加密强度高,很难破解。缺点也很明显,即密钥本身容易被泄漏。尤其是考虑到数量庞大的Client端,很难保证密钥不被泄露。一旦一个Client端的密钥被窃据,那么整个系统的安全性也就不复存在。因此,如何保存密钥成为了关键问题。于是引出了第二种加密方式:非对称加密。
1-2、非对称加密
在非对称加密中有两个密钥,公钥和私钥。这两个密钥配对产生和使用。用公钥加密的数据,必须用与其对应的私钥才能解开。并且,私钥无法通过公钥获取。因此,公钥是可以被公开的,而私钥则必须被安全存放。
图片.png- 远程Server收到Client端用户TopGun的登录请求,Server把自己的公钥发给用户。
- Client使用这个公钥,将密码进行加密。
- Client将加密的密码发送给Server端。
- 远程Server用自己的私钥,解密登录密码,然后验证其合法性。
若验证结果,给Client相应的响应。
1-3、中间人攻击
上述流程会有一个问题:Client端如何保证接受到的公钥就是目标Server端的,如果一个攻击者中途拦截Client的登录请求,向其发送自己的公钥,Client端用攻击者的公钥进行数据加密。攻击者接收到加密信息后再用自己的私钥进行解密,不就窃取了Client的登录信息了吗?这就是所谓的中间人攻击。
图片.png解决中间人攻击的重点就是需要确保客户端接收到的公钥是目标服务端生成的。
二、SSH详解
SSH(Secure Shell)是一个提供数据通信安全、远程登录、远程指令执行等功能的安全网络协议,最初提出目的是替代非安全的Telnet、rsh、rexec等远程Shell协议。之后SSH发展了两个大版本SSH-1和SSH-2。
OpenSSH是目前免费的、最流行的SSH实现软件,在很多操作系统中都默认安装了OpenSSH。
2-1、SSH基本框架
图片.pngSSH协议框架中最主要的部分是三个协议:
- 传输层协议(The Transport Layer Protocol)提供服务器认证,数据机密性,信息完整性 等的支持;
- 用户认证协议(The User Authentication Protocol) 则为服务器提供客户端的身份鉴别;
- 连接协议(The Connection Protocol) 将加密的信息隧道复用成若干个逻辑通道,提供给更高层的应用协议使用; 各种高层应用协议可以相对地独立于SSH基本体系之外,并依靠这个基本框架,通过连接协议使用SSH的安全机制。
同时SSH协议框架中还为许多高层的网络安全应用协议提供扩展的支持。它们之间的层次关系可以用如下图来表示:
图片.png2-2、SSH的加密
2-2-1、SSH加密方式
SSH从安全和性能两方面综合考虑,结合使用了 Public Key/Private key(公钥/私钥) 和 Secret Key(密钥)。
Public Key/Private key:非对称加密,安全,但效率低,不适合大规模进行数据的加密和解密操作
Secret Key:对称机密,高效,但安全性相对较低,Key的分发尤其不方便
2-2-2、SSH中的key
名称 | 生命周期 | 创建 | 类型 | 描述 |
---|---|---|---|---|
Host Key | 持久化 | 服务端 | Public Key | Host Key是服务器用来证明自己身份的一个永久性的非对称密钥 |
User Key | 持久化 | 用户 | Public Key | User Key 是客户端用来证明用户身份的一个永久性的非对称密钥(一个用户可以有多个密钥/身份标识) |
Server Key | 默认为1小时 | 服务端 | Public Key | Server Key 是SSH-1协议中使用的一个临时的非对称密钥,每隔一定的间隔(默认是一个小时)都会在服务器重新生成。用于对Session Key进行加密(仅SSH-1协议有,SSH-2对其进行了增强,这里Server Key作为一个概念便于在流程中进行描述) |
Session Key | 客户端 | 会话(Session) | Secret Key | Session Key是一个随机生成的对称密钥,用户SSH客户端和服务器之间的通信进行加密,会话结束时,被销毁 |
2-3、SSH安全连接的建立过程
SSH处理过程可以分解成几个主要阶段:
- 协议协商阶段
- 服务端认证阶段
- 客户端认证阶段
- 数据传输阶段
每个阶段均涉及到客户端与服务端的多次交互,通过这些交互过程完成包括证书传输、算法协商、通道加密等过程。
2-3-1、协议协商阶段
- 服务端打开端口22,等待客户连接。
- 客户端向服务端发起TCP连接,双方完成握手并建立连接。
- 服务端向客户端发送第一个报文,包括版本标志字符串,格式为 “协议版本号 次协议版本号 软件版本号”。
- 客户端收到报文后,解析协议版本号,如果服务端的协议版本号比自己的低,且客户端能支持服务端的低版本,就使用服务端的协议号,否则使用自己的协议版本号。
- 客户端回复服务端一个报文,包含了客户端决定使用的协议版本号。服务端比较客户端发过来的版本号,决定是否能同客户端交互。
- 如果协商成功,就进入下一阶段。否则服务端断开TCP连接。
2-3-2、服务端认证阶段
完成协议协商阶段后,客户端与服务端已经建立明文的通信通道,之后进入服务端认证阶段。
SSH协议中没有明确的服务端认证过程,而通过一系列的服务端与客户端的交互来确定服务端的身份,该过程还会完成Host Key、User Key、Session Key等在客户端与服务端之间的传输。
1)建立连接后,服务端向客户端发送:
- Host Key:用于认证服务端的身份
- Server Key:用于帮助建立安全的数据传输通道
- 8字节的随机数,即检测字节(check bytes):客户端通过在下一次响应中包含该随机数,防止IP地址欺诈
- 服务端支持的加密算法、压缩方式和认证方式
这个时候,客户端和服务端使用Host Key、Server Key和检测字节生成一个128位的MD5值,作为此次会话的Session id。
2)客户端在接收到服务端Host Key后,会检查自己的knows host数据库中(一般为~/.ssh/know_hosts文件),是否已经包含当前服务端的Host Key,如果有则继续下一步;如果没有或包含当前服务端的其他Host Key,则由用户决定是否信任该服务端,或终止当前连接。
The authenticity of host 'ssh-server.example.com (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?
如果客户端拒绝接受这个主机密钥,那么连接就中止了。否则,继续。
3)客户端向服务端发送Session Key
出于性能考虑,SSH采用对称加密(Secret Key),对实际通信内容进行加密,即Session Key。因此Session Key的安全尤为重要,一旦Session Key泄漏给攻击者,那所有的通信数据都可能被攻击者截获。由于当前通道还是采用明文方式,客户端采用Host Key和Server Key对Session Key进行两次加密来加强安全性,同时还会发送检测字节和所选定的算法(这些算法是从第1步中服务器支持的算法列表中挑选出来的)。
4)服务端得到Session Key后,客户端和服务端就可以通过Session Key对数据进行加密解密操作,到此,双方完成安全(加密)通道的建立。 Host Key和Server Key都是Public Key(非对称加密),只有通过服务端的私钥(Private Key)才能对其解密,以得到Session Key。在正式使用安全通道前,客户端要求服务端发送使用Session Key加密的确认信息,以验证服务端的身份。 为避免Session Key的泄漏,SSH还采取了其他安全措施,Session Key仅保存在内存避免其泄漏;周期性更换Server Key,默认为1小时(SSH 2对Server Key安全进一步增强)。
2-3-3、客户端认证阶段
SSH提供多种客户端认证方式。这里之讨论我们经常使用的的Password和Public Key方式。
此时安全通道已经及建立,之后的所有内容都通过Session Key加密后进行传输。
1)Password
Password 方式既客户端提供用户和密码,服务端对用户和密码进行匹配,完成认证。类Unix系统中,如 OpenSSH 的框架,一般通过系统的本地接口完成认证。
Password 的优势是简单,无需任何而外的配置就可以使用。缺点密码不便于记忆,过于简单的密码容易被暴力破解。
2)Public Key
Public Key认证的基本原理是基于非对称加密方式,分别在服务端对一段数据通过公钥进行加密,如果客户端能够证明其可以使用私钥对这段数据进行解密,则可以说明客户端的身份。因为服务端需要使用客户端生成的密钥对的公钥对数据首先加密,所以需要先将公钥存储到服务端的密钥库(Auhtorized Key)。还记得Github中使用git协议push代码前需要先添加SSH KEY吗?
下面详细介绍一个通过Public Key进行客户端认证的过程。
1) 客户端发起一个Public Key的认证请求,并发送RSA Key的模数作为标识符。(如果想深入了解RSA Key详细 --> 维基百科)
2)服务端检查是否存在请求帐号的公钥(Linux中存储在~/.ssh/authorized_keys文件中),以及其拥有的访问权限。如果没有则断开连接
3)服务端使用对应的公钥对一个随机的256位的字符串进行加密,并发送给客户端
4)客户端使用私钥对字符串进行解密,并将其结合session id生成一个MD5值发送给服务端。 结合session id的目的是为了避免攻击者采用重放攻击(replay attack)。
5)服务端采用同样的方式生成MD5值与客户端返回的MD5值进行比较,完成对客户端的认证。
2-3-4、数据传输阶段
该阶段通过Session Key提供的对称加密(Secret Key)算法,保证需要传输的任何数据的安全。
SSH整体过程如下:
图片.png
网友评论