关于SSH加密和连接的若干事儿

概述

SSH全称secure shell,是一种网络传输协议,是最常用的安全管理远程服务器的协议和工具集。SSH协议中使用多种加密技术保证在用户终端和服务器之间建立加密安全连接,连接双方通过互相握手验证,并通过加密的通道传递管理命令和执行结果。

本文中,虫虫将以此为话题和大家一起学习下SSH协议中涉及的基础加密技术以及怎么利用这些技术构建安全的通讯。此信息可用于了解各种常见的加密技术,SSH加密层、安全连接构建步骤以及双方互相验证步骤能内容。

SSH算法

SSH为了确保信息的安全传输,从连接发起到完成各阶段的各个点SSH协议采用了许多不同类型的数据加密技术,包括可逆的对称加密,非对称加密以及不可逆的哈希散列。

对称加密

加密和解密数据的时候相互对应的关系决定了加密方案是对称加密还是非对称的加密。

最常见的加密方法是对称加密,对称加密是一种加密类型,在加密和解密时候使用同一个密钥。所以,在对称加密中,任何人都可以利用该密钥加密消息和解密任何使用它加密的消息。这种加密方法通常也称为”共享密钥”加密或”密钥”加密。通常只有一个密钥用于所有加解密操作,或者使用一对密钥,但是这对密钥可以互相简单推算出彼此。

关于SSH加密和连接的若干事儿

SSH数据传输时候基本上所有过程都是使用对称密钥来加密。只有在刚开始创建连接阶段和身份认证握手阶段才使用非对称加密。

客户端和服务器都通过协商一致的算法生成密钥,并互相通过可信通道交换密钥,这个过程叫密钥交换。通过密钥交换服务器和客户端可共享某些公共数据结合自己隐秘数据通过算法各自获得相同的共享密钥。后面第二部分虫虫会对此过程进行详细解释。此过程创建的对称加密密钥是基于会话的,然后通过该会话在服务器和客户端之间发送的加密数据。会话一旦创建,此后所有数据数据都通过共享密钥加密。

在对称加密过程中最重要的是加密算法。SSH中支持各种不同的加密算法,主要有AES,Blowfish,3DES,CAST128和Arcfour等等。服务器和客户端可以根据优先顺序协商其支持的密码列表。服务器上可用的客户端列表中的第一个选项就是密码算法。

在虫虫的Centos 中,openssh7.4是默认的算法为在连接github的git服务过程中,ssh协商的算法为:

chacha20-poly1305@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc

这样连接协商后的结果会使用chacha20-poly1305@openssh.com做认证密码,共享加密算法为aes256-ctr。

关于SSH加密和连接的若干事儿

我们注意到加密算法使用了ChaCha20-Poly1305,它是由Google 推出新的加密套件并,具有以下优势:ChaCha20-Poly1305 避开了现有发现的所有安全漏洞和攻击;Poly1305 的输出是 16 字节,而 HMAC-SHA1 是 20 字节,可以节省 16% 的 overhead 消耗。

非对称加密

关于SSH加密和连接的若干事儿

非对称加密与对称加密的不同之处在于,为了在单个方向上发送数据,需要两个相关的一组密钥。其中一个密钥称为私钥,而另一个称为公钥。

公钥可以公开共享。私钥与之配,无法通过公钥计算出公钥。公钥和私钥之间从数学的特性保证公钥加密的信息只能由私钥解密,私钥加密的信息也不能用公钥解密。

非对称加密中是用最广泛RSA算法就用到了利用大素数方便生成大整数(2048),但是该大素数则几乎无法分解的特性。最近热门的阿蒂亚老教授宣布证明《黎曼猜想》,就是用关于大素数分布的规律,如果该证明有效,能发现大素数的分布规律,则可能会影响大素数分解,读广泛使用的RSA算法可能产生影响。

关于SSH加密和连接的若干事儿

有意思的是RSA算法曾暴露过一丑闻,数学家们发现,算法中曾经使用的一个随机函数DUAL_EC_DRBG被NSA做了手脚,植入了后门,可以过这个这个算法来推算密钥。NSA利用该算法监控和窃取一些加密信息。

关于SSH加密和连接的若干事儿

我们知道密钥对中的私钥唯一用来解密消息的密钥,所以私钥要绝对保密,不能泄露给任何人。实践中除了保证私钥的存放外,SSH中用来进行系统认证的私钥虫虫建议应该对其设置密码,防止万一泄露,没有密码别人也用不了。如果是系统之间做自动程序和访问git操作的密钥,为了方便可以不设置密码。

SSH在建立对称加密(用于加密会话)的初始密钥交换过程中,使用了非对称加密。在该阶段,双方都生成临时密钥对并互相交换公钥,以便产生将用于对称加密的共享密钥。

SSH还通过使用非对称加密的来进行SSH密钥的身份验证:客户端创建密钥对,然后将公钥配置到远程服务器上,具体为用户帐户目录的~/.ssh目录下名为authorized_keys文件,每一行对应一个公钥。

收到用户请求后,服务器端利用authorized_keys中公钥比对证书指纹,找到用户公钥加密一个消息,并对消息生成哈希串附加到消息后返回给客户端。如果客户端能利用自己私钥解密消息,并用自己手中服务器端的公钥加密验证串给服务器,服务用自己私钥解密消息完成认证,这样证书交换和身份认证过程完成(密钥交换过程中各自独立计算出了对称加密的共享密钥),开始进行加密数据传输。

哈希散列

SSH协议中还用到了加密散列。哈希散列算法是一种不可逆算法,除非你知道原始值生成散列对比,否则你永远无法通过散列算出原始值(但是可以通过哈希碰撞,就是利用可能字串或者构造彩虹表大量生成哈希进行对比,目前MD5和SSA1已经不再绝对安全)。散列算法常用于创建信息 “签名”或生成一组信息摘要,用来保证信息传输过程中没有被人认为篡改。因为对数据的任何修改都会导致其哈希完全不一致。

注意:目前对MD5和SHA-1可以通过大量计算生成利用精心设置的数据将数据内容修改,但是能保证哈希不变。下图就是谷歌去年2月份的SHA-1碰撞的实验,两个背景完全不一样的pdf,但是生成哈希完全一样。

关于SSH加密和连接的若干事儿

在SSH对称加密协商的过程中,选择消息认证码(MAC)的生成算法就是用的哈希算法。协商发送的每条加密信息都会附加公开的该信息MAC作为消息的一部分,以便于另一方可以用它验证数据包的完整性。 MAC根据对称共享密钥,消息的分组序列号和实际信息组成的内容算出来的。MAC作为数据包的最后部单独发送。

常见加密算法比较

下面参考网上资料,我们对常见加密算法比较图示:

关于SSH加密和连接的若干事儿

常用的对称加密算法:

关于SSH加密和连接的若干事儿

常用非对称算法比较

关于SSH加密和连接的若干事儿

常用散列算法比较

关于SSH加密和连接的若干事儿

SSH工作原理

我们上面在第二部部分SSH算法中概要提到了SSH的工作原理,本部分虫虫会详细介绍下。

SSH协议使用客户端/服务器(CS)模式来双方认证并彼此加密传输数据。服务器组件侦听指定的端口(默认22),接受连接。服务器端(SSHD)负责协商安全连接,验证客户端,并在完成认证后,初始化shell环境。

客户端负责开始与服务器的初始TCP握手,协商安全连接,验证服务器的身份(记录的信息匹配,~/.ssh/known_hosts中保存的证书,第一链接时候需要手动输入Yes,确认链接该服务器,并记录域名,端口,IP和公钥),以及提供身份验证密码(密钥)。

SSH会话分两个阶段建立:基于Diffie-Hellman算法的密钥交换过程和用户认证阶段。

密钥交换(Diffie-Hellman)

当客户端建立TCP连接时,服务器会使用它支持的协议版本进行响应。如果客户端可以匹配其中一个可接受的协议版本,则继续连接。服务器还提供其公共主机密钥,客户端可以使用该密钥来检查这是否是预期要访问的主机。

双方使用称为Diffie-Hellman算法协商会话密钥。该算法使得每一方能够将他们自己的私有数据与来自另一系统的公共数据组合以算出相同的共享会话密钥。

关于SSH加密和连接的若干事儿

该密钥交换过程步骤如下:

1、双方约定一个大的素数,它将它作为随机种子。

2、双方约定加密算法(通常为AES),此后利用该算法加密数据。

3、会话双方独各生成另一个素数,该数字保密。该素数用用于双发交互的临时私钥。

4、利用各自私钥,共享大素数和加密算法生成公钥,并与对方交换公钥。

5、接受方利用自己的私钥,对方公钥和原始共享素数来计算共享密钥。虽然这个过程各自独立,都使用自己私钥和对方公钥,所以能生成相同共享密钥。

7.然后使用共享密钥加密此后的所有通信。

生成的秘密是对称密钥,所以双方都可以解密消息。该过程保证了,随后数据通信位于一个加密隧道中。

用户认证

会话加密通道建立后,SSH开始进入用户认证阶段。该阶段完成用户验证和访问权限确定。根据服务端的配置(sshd_config),可能使用一下几种身份验证方法:

1、密码验证:服务器提示客户端输入用户名和密码。密码通加密隧道发送,对外方是安全的。

由于该方法存在暴力破解,以及容易泄密的可能较大,虫虫不建议使用此方法,尤其是直接使用root登陆,危害性更大。

2、使用openssh密钥对认证:

关于SSH加密和连接的若干事儿

具体步骤如下:

(1)、客户端首先向服务器发送要对其进行身份验证的密钥对的用户名。

(2)、服务器检查客户端尝试登录用户帐户的下authorized_keys文件。

(3)、如果在文件中找到具有匹配公钥,则服务器生成随机数并使用公钥加密该随机数。并该加密消息发送给客户端。

(4)、如果客户端利用自己的私钥解密消息(如果可以的话),从而显示原始数。

(5)、客户端将解密的原始数和用于加密通信的共享会话密钥组合,计算他们的哈希值。客户端将该哈希值发回服务器,作为回应。

(6)、服务器使用相同的共享会话密钥和此前(步骤4)发送给客户端的原始编号来自行计算哈希值。将计算结果和客户端发回的哈希值对比。如果这两个值匹配,则证明客户端拥有私钥并且客户端已经过身份验证。

3、它认证方法:比如结合ldap的认证,双因子认证,以及更安全的Kerberos地狱狗认证以后有机会再做介绍,此处不再赘述

关于SSH加密和连接的若干事儿

本文中,虫虫结合SSH过程,介绍常见的加密算法,以及基于密钥交换和用户认证等,希望能帮助你理清SSH认证的过程。虫虫在此需要指出的是,类似的体系也在其他安全通讯中使用,比如用的比SSH更广泛的HTTPS的SSL/TSL技术。