SSH (Secure Shell)
1. SSH简介
SSH 是 Secure Shell(安全外壳)的简称。
用户通过一个不能保证安全的网络环境 远程登录到设备时,SSH 可以利用加密和强大的认证功能提供安全保障,保护设备 不受诸如 IP 地址欺诈、明文密码截取等攻击。
2. SSH2与SSH1区别
1.在SSH1的联机过程中,当Server接受Client端的Private Key后,就不再针对该次联机的Key pair进行检验。此时若有恶意黑客针对该联机的Key pair对插入恶意的程序代码时,由于服务端你不会再检验联机的正确性,因此可能会接收该程序代码,从而造成系统被黑掉的问题。
2.为了改正这个缺点,SSH2 多加了一个确认联机正确性的Diffie-Hellman机制,在每次数据传输中,Server都会以该机制检查数据的来源是否正确,这样,可以避免联机过程中被插入恶意程序代码的问题。也就是说,SSH2 是比较安全的。
3. SSH2工作过程
3.1 版本号协商阶段
具体步骤如下:
① 服务器打开端口 22,等待客户端连接。
②客户端向服务器端发起 TCP 初始连接请求,TCP 连接建立后,服务器向客户 端发送第一个报文,包括版本标志字符串,格式为“SSH-.< 次协议版本号>-”,协议版本号由主版本号和次版本号组成, 软件版本号主要是为调试使用。
③客户端收到报文后,解析该数据包,如果服务器端的协议版本号比自己的低, 且客户端能支持服务器端的低版本,就使用服务器端的低版本协议号,否则使 用自己的协议版本号。
④ 客户端回应服务器一个报文,包含了客户端决定使用的协议版本号。服务器比 较客户端发来的版本号,决定是否能同客户端一起工作。
⑤如果协商成功,则进入**和算法协商阶段,否则服务器端断开 TCP 连接。
上述报文目前为止都是采用明文方式传输的。
封包流程:
3.2 **和算法协商阶段
具体步骤如下:
①服务器端首先生成 RSA 或 DSA **对,用于参与会话** SessionKey 的生成。
②服务器端和客户端分别发送算法协商报文给对端,报文中包含自己支持的公钥 算法列表、加密算法列表、MAC(Message Authentication Code,消息验证 码)算法列表、压缩算法列表等。
③ 服务器端和客户端根据对端和本端支持的算法列表得出最终使用的算法。
④服务器端和客户端利用 DH 交换(Diffie-Hellman Exchange)算法、主机** 对等参数,生成会话** SessionKey 和会话 ID。
⑤通过以上步骤,服务器端和客户端就取得了相同的会话**SessionKey和会话 ID。对于后续传 输的数据,两端都会使用会话**SessionKey进行加密和解密,保证了数据传送的安全。在认 证阶段,两端会使用会话 ID 用于认证过程。
Diffie-Hellman:
DH算法的最终目的是为了完成通信双方对称秘钥的交互,但是即使处在不安全的环境(有人侦听)也不会造成秘钥泄露。
这里举一个最简单的例子:A和B要进行银行密码的交换,他们需要一个秘钥来加密自己的信息,A发给B ‘2’ 作为暗号,B再回一个‘2’。以后他们发的所有信息都将加2。现在C偷听到了,A发一‘456’给B,那么C知道A的银行密码是‘234’了。
有了DH就不一样了,A和B协定用23和5运算(AB公有),A想了一个6(A私有),A用6、23、5算出来一个8,发给B; B想了一个15(B私有),B用15、23、5算出来一个19又发给A;
现在A用B发过来的19可以算出2,B用A发过来的8算出来也是2,所以他们以后发的信息都是加2的。
假设C一直在偷听,那么他知道一开始用的是23和5,还有发送过程中的8和19,然而这并没有什么卵用,因为他不知道A、B私有的6、15,所以之后A和B交换的银行密码‘456’ 他也就没法**了。
至于“为什么要选择23和5、8和19还有最后的2是怎么算出来的、为什么C有生之年都算不出来”见 Diffie-Hellman算法:
会话秘钥Session Key重要性:
①SSH采用对称加密(Secret Key),对实际通信内容进行加密,即Session Key。因 此Session Key的安全尤为重要。
②为避 免Session Key的泄漏,SSH还采取了其他安全措施,Session Key仅保存在内存避免其泄漏。
Diffie-Hellman封包流程:
3.3 认证阶段
具体步骤如下:
①客户端向服务器端发送认证请求,认证请求中包含用户名、认证方法、与该认 证方法相关的内容(如:password 认证时,内容为用户名+密码)。
②服务器端对客户端进行认证,如果认证失败,则向客户端发送认证失败消息, 其中包含可以再次认证的方法列表。
③客户端从认证方法列表中选取一种认证方法再次进行认证。
④该过程反复进行,直到认证成功或者认证次数达到上限,服务器关闭连接为止。
3.3.1 password 认证
①远程Server收到Client端用户的登录请求,Server把自己的公钥发给用户。
②Client使用这个公钥,将密码进行加密。
③Client将加密的密码发送给Server端。
④远程Server用自己的私钥,解密登录密码,然后验证其合法性。
⑤若验证结果,给Client相应的响应。
3.3.2 Public Key认证
①Client将自己的公钥手动存放在Server上,追加在文件authorized_keys中。
②Server端接收到Client的连接请求后,会在authorized_keys中匹配到Client的公钥pubKey,并生成随机数 R,用Client的公钥对该随机数进行加密得到pubKey(R) ,然后将加密后信息发送给Client。
③ Client端通过私钥进行解密得到随机数R,然后对随机数R使用会话秘钥SessionKey生成MD5,发送给Server端。
④Server端会也会对R使用会话秘钥SessionKey加密生成MD5。
⑤Server端会最后比较两个MD5是否相同,完成认证过程。
3.3.3 所有key的关系