1 https
SSL(Secure Sockets Layer) 安全套接层,是一种安全协议,经历了 SSL 1.0、2.0、3.0 版本后发展成了标准安全协议 - TLS(Transport Layer Security) 传输层安全性协议。TLS 有 1.0 (RFC 2246)、1.1(RFC 4346)、1.2(RFC 5246)、1.3(RFC 8446) 版本。
1.1 安全协议必备元素
在一个不安全的信道传输,我们需要保证三点:
(1)一是保证数据来源可靠性(身份认证)及在通信过程中数据的完整性(防篡改和防伪造),有数字签名和HMAC两种做法。数字签名是用私钥对报文进行签名生成数字签名,然后公钥对数字签名进行验证,常见的有SM2,RSA等;HMAC是通信两边用同一个密钥,运行常见的哈希函数MD5,SHA-1等进行哈希运算生成字符串,然后两边生成的字符串进行比较。具体细节,请参见XXXXXXXXX。
(2)另外一种是保证数据机密性,即对数据进行加密传输,加密算法分为对称算法和非对称算法,非对称算法有两个密钥,公钥加密,私钥解密,安全性较高,但加解密速度较慢,例如RSA加密算法;对称算法只有一个密钥,对称算法又分流加密(CR4等)和分组密码算法(AES,3DES等),流加密速度更快,相比于非对称加密,对称算法加解密速度较快,安全性较低。
(3)防重放:加入新鲜因子,随机数等.
因此通常一个安全协议的设计需要满足基础三点,保证数据完整性(防篡改)和机密性,综合效率及安全性分析,通常的做法是将对称算法与非对称算法结合使用,即利用非对称算法协商出一个会话密钥,然后会话密钥作为对称算法的密钥进行加密,HMAC运行。
1.2 TSL 协议体系结构
TLS的体系结构中包含两个协议子层,其中底层是SSL记录协议层(SSL Record Protocol Layer);高层是SSL握手协议层(SSL HandShake Protocol Layer)。
TLS协议主要分为两层:
(1) TLS记录协议层的作用是为高层协议提供基本的安全服务。TLS记录协议针对HTTP协议进行了特别的设计,使得超文本的传输协议HTTP能够在TLS运行。纪录封装各种高层协议,具体实施压缩解压缩、加密解密、计算和校验MAC等与安全有关的操作。
(2) TLS握手协议层包括握手协议(HandShake Protocol)、密码参数修改协议(Change Cipher Spec Protocol)和告警协议(Alert Protocol)。握手层的这些协议用于管理信息的交换,允许应用协议传送数据之间相互验证,协商加密算法和生成密钥等。
其中最重要的是记录协议和握手协议:
(1) TLS记录协议:它建立在可靠的传输(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能。
(2) TLS握手协议:它建立在TLS记录协议之上,用于在实际的数据传输开始之前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
如下图所示,可以看到TLS握手层是建立在TLS记录层之上的。
1.3 TLS密码套件结构
密码套件是客户端与服务器约定交互过程中需要的密码算法系列,如上图所示,以TLS开头,
(1)第一个参数为密钥交换算法,即协商预主密钥pre-master key所用的算法,主要有两类。分别是
(a)基于Diffie-Hellman交换算法的:ECDHE,DHE,DH,ECDH
DH密钥交换原理如下图,图中的k即为pre-master key:
DH和ECDH主要不同在于基于的困难问题稍有不同,DH是基于离散对数困难问题,而ECDH是基于椭圆曲线上的离散对数问题;任何基于离散对数上的都可以换算到椭圆曲线上。椭圆曲线上密钥长度只需要较短的即可达到基础域中较长的安全性,例如160比特的椭圆曲线密钥和1024比特的RSA密钥的安全性相当。越小的密钥在速度、效率、带宽、存储上有着许多优势 。
对于DHE与DH的主要不同在于后面有个E,E代表了“临时”,即在握手流程中,作为服务器端,ECDH少了一步计算Pb的过程,Pb用证书中的公钥代替,而证书对应的私钥就是Xb。由此可见,使用ECDH密钥交换算法,服务器必须采用ECC证书;服务器不发送server key exchange报文,因为发送certificate报文时,证书本身就包含了Pb信息。
(b)基于RSA的密钥交换算法:客户端利用RSA公钥加密pre-master key,服务器端私钥解密出预主密钥
综上几种密钥交换算法比较如下表所示:
ECDHE | ECDH | DHE | DH | RSA | |
---|---|---|---|---|---|
server key exchange | Y | N(证书中的公钥Pb) | Y | N(证书中的公钥及Pb) | N |
前向安全性 | Y | N | Y | N | N |
(2)第二部分为身份认证算法,即数字签名算法,这里根据密码套件不同,代表的含义也不同。
(a)密钥交换算法为ECDHE情况下,签名算法指的是 serverkeyexchange被签名的算法,只有2种ECDSA和RSA,具体是哪种完全取决于证书的公钥类型(ECC RSA)。如果你的证书是ECC公钥,那么服务器不可能选择ECDHE_RSA这种套件。
(b)ECDH的情况下,签名算法 指的是 证书自身的被签名算法。 如果服务器部署的是RSA签名算法的证书,那么必须使用ECDH_RSA套件;反之亦然。
(3)第三部分AES_128_GCM,主要为加密算法,一般是加密算法+加密强度(128位/256位)+工作模式(CBC/GCM),用于后面加密传输所用的算法,保证数据传输过程中的机密性。
(4) 第四部分SHA256为哈希算法,用于HMAC和PRF,保证数据在传输过程中的完整性。
2 https协议总框架
如下图为https协议总框架,首先
非对称协商会话密钥,然后用会话密钥加密传输。
下面以具体wireshark抓包具体报文进行解说。(密码套件TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256为例)拦截www.google.com的https连接报文。其中2.1到2.6为握手层协议,2.7为记录协议.
2.1 Client hello
这条消息是客户端向服务器端发送连接请求。
Version: 协议版本(protocol version)指示客户端支持的最佳协议版本
Random: 一个 32 字节数据,28 字节是随机生成的 (图中的 Random Bytes);剩余的 4 字节包含额外的信息,与客户端时钟有关 (图中使用的是 GMT Unix Time)。在握手时,客户端和服务器都会提供随机数,客户端的暂记作 random_C (用于后续的密钥的生成)。这种随机性对每次握手都是独一无二的,在身份验证中起着举足轻重的作用。它可以防止 重放攻击,并确认初始数据交换的完整性。
Session ID: 在第一次连接时,会话 ID(session ID)字段是空的,这表示客户端并不希望恢复某个已存在的会话。典型的会话 ID 包含 32 字节随机生成的数据,一般由服务端生成通过 ServerHello 返回给客户端。
Cipher Suites: 密码套件(cipher suite)块是由客户端支持的所有密码套件组成的列表,该列表是按优先级顺序排列的.
Cipher Suites (19 suites)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
Compression: 客户端可以提交一个或多个支持压缩的方法。默认的压缩方法是 null,代表没有压缩
Extensions: 扩展(extension)块由任意数量的扩展组成。这些扩展会携带额外数据
2.2 Server hello
这条消息是服务器对client hello的响应。
这个消息的结构与 ClientHello 类似,只是每个字段只包含一个选项,其中包含服务端的 random_S 参数 (用于后续的密钥协商)。服务器无需支持客户端支持的最佳版本。如果服务器不支持与客户端相同的版本,可以提供某个其他版本以期待客户端能够接受。
图中的 Cipher Suite
是后续密钥协商和身份验证要用的加密套件TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,此处选择的密钥交换与签名算法是 ECDHE_RSA,对称加密算法是 AES-128,后面会讲到这个
还有一点默认情况下 TLS 压缩都是关闭的,因为 CRIME 攻击会利用 TLS 压缩恢复加密认证 cookie,实现会话劫持,而且一般配置 gzip 等内容压缩后再压缩 TLS 分片效益不大又额外占用资源,所以一般都关闭 TLS 压缩
2.3 Certificate
典型的 Certificate 消息用于携带服务器 X.509 证书链。 服务器必须保证它发送的证书与选择的算法套件一致。
2.3.1 证书内容
注意证书链的顺序,最下层证书在前(用户证书在前,上级证书在后)。发送的证书是二进制格式,并非base64之后的格式。有个技巧,在wireshark右键“导出分组字节流”功能,然后保存证书,后缀为der,是可以变成一个正常证书的(二进制格式)。
下面对证书内容进行分析:
图中从右到左分别是1级根证书为Google Trust Services,二级中间证书为GTS CA,三级证书为google-analytics;从上到下为每个证书中的详细信息。
首先需要特别说明证书中的重点内容是什么?
(1)版本:Version,V3。对应的是X.509 V3标准
(2)序列号:证书颁发者唯一序列号
(3)签名算法:注意!证书中的签名算法指的是上级证书运行的签名算法,生成数字签名的;而不是
本级证书拥有的签名算法。例如,3级证书中的签名算法为sha256RSA,应该与2级证书的公钥RSA是一致的。
(4)签名哈希算法:同样是上级证书签名时用的哈希算法。
(5)公钥及公钥参数:注意本即证书的公钥,该公钥不是用于验证2级证书生成的数字签名的.**该公钥是用于后面server key exchange的;具体用法如下:
(a)对于ECDHE和DHE密钥交换算法,服务器端需要server key exchange,发送用于DH的公钥Pb及对公钥的数字签名(防止公钥在通信过程被篡改),那服务器证书的公钥就是用来验证该签名的;
(b)对于不需要server key exchange的DH,ECDH密钥交换算法,服务器证书中的公钥就是DH密钥交换的Pb;
(c) 对于不需要server key exchange的RSA密钥交换算法:服务器证书中的公钥是用于加密第三个随机数预主密钥pre-master key的.
2.3.2 证书验证过程
证书链验证过程如下:(简易图)
首先利用一级证书中的RSA公钥验证二级证书,再用二级证书中的RSA公钥验证三级证书,即服务器证书;服务器证书中的ECC公钥,公钥参数ECDSA用于密钥交换,具体功能在2.3.1已阐述;
2.4 第三个随机数的密钥协商
不同的密码套件,也会有不一样的密钥协商算法具体1.3节已分析;该次交互选择的密码交互算法为ECDHE_ECDSA;
2.4.1 Server key exchange
从下面可以看到报文信息如下:
(1)公钥Pubkey:服务器端发送Pb(对应的私钥为b),以及DH用到的相关参数,比如选择的椭圆曲线等
(2)数字签名Signature:服务器利用私钥b运行ECDSA签名算法生成的数字签名,保证公钥来源的可靠性和完整性,客户端收到该签名后,用之前收到的服务器证书中的ECC公钥进行签名验证.
2.4.2 Client key exchange
客户端发送公钥Pa
然后双方根据Diffie-Hellman算法分别计算出pre-master key;具体计算过程在1.3已写.
2.5 Finished (Encrypted Handshake Message)
这个报文的目的就是告诉对端自己在整个握手过程中收到了什么数据,发送了什么数据。来保证中间没人篡改报文。客户端和服务器端都会分别发送.
其次,这个报文作用就是确认密钥的正确性。因为Encrypted handshake message是使用对称密钥进行加密的第一个报文,如果这个报文加解密校验成功,那么就说明对称密钥是正确的。
计算方法也比较简单,将之前所有的握手数据(包括接受、发送),计算md运算,然后计算prf,然后就是使用协商好的对称密钥进行加密了。 ( 从client hello开始,到目前准备发送“Encrypted handshake message”前,自己所有收到和发送的handshake类型的握手数据。 )
2.6 密钥产生
如上图所示,此时客户端,服务器端都已经获取全部的计算协商密钥需要的信息: 两个明文随机数 CR 和 SR与自己计算产生的 Pre-master,然后得到主密钥master.为了保证信息的完整性和机密性,TSL需要有六个密钥:四个密钥和两个IV。为了信息的可信性,客户端需要一个密钥(HMAC),为了加密要有一个密钥,为了分组加密要一个IV,服务也是如此。
master= PRF(Pre_master, "master secret", CR + SR)
2.6.1 生成主密钥Master key
主密钥Master key的生成如下,图中的MD5算法是在密码套件中指定的;根据三个参数预备主密钥PM,服务器端随机数SR,客户端随机数CR,经过不断的迭代,最终生成48字节的主密钥master key.
2.6.2 生成密钥材料
密钥材料需要以下6个,具体生成过程如下图所示.
(1)客户端MAC密钥 :Auth .Key
(2)服务器端MAC密钥 :Auth .Key
(3) 客户端加密密钥及IV:Enc.key
(4) 服务器端加密密钥及IV:Enc.key,IV
(5) 客户端分组密码需要的IV
(6) 服务器端分组密码需要的IV
2.7 记录协议
记录协议负责在传输连接上交换的所有底层消息,并且可以配置加密。每一条 TLS 记录以一个短标头开始。标头包含记录内容的类型 (或子协议)、协议版本和长度。原始消息经过分段 (或者合并)、压缩、添加认证码、加密转为 TLS 记录的数据部分。 如下图所示.对应用数据进行分段,对分段信息先压缩,在加上对压缩进行的MAC,然后对压缩信息+MAC进行加密,最后加记录头,形成报文,发送.
报文如下:
3 https 安全性分析
3.1 TLS版本的选择
目前在SSL/TLS家族中主要有7个协议: SSL v2, SSL v3, TLS v1.0, TLS v1.1, TLS v1.2和TLSv1.3。
1 SSL v2, SSL v3, TLS v1.0 , TLS v1.1协议均有明确的安全缺陷
SSL v2: DROWN攻击
SSL v3: POODLE攻击
TLS v1.0: BEAST和POODLE攻击
TLS v1.1 密码套件较老,已不安全
2、TLS v1.2与v1.3目前均无已知的安全缺陷
推荐使用TLS v1.2与v1.3.
3.2 密码套件的选择
3.2.1 根据证书去选择密码套件
当服务器配置ECC证书时,加密套件只能选择XXX_ECDSA_XXX或者ECDH_XXX。
当服务器配置RSA证书时,只能选择RSA_XXX或者ECDHE_RSA_XXX形式的加密套件。
需要注意的是,如果加密套件选择ECDH_RSA或者ECDH_ECDSA时,由于ECDH加密套件默认表明了握手需要ECC证书(即ECC证书的公钥充当握手中server key exchange中的公钥,证书的私钥同样也是握手过程中的私钥,握手过程不需要server key exchange),所有第二部分RSA和ECDSA表明的是想要的上级签发该类型的服务器证书。
如果加密套件选择ECDHE_XXXX,则第二部分RSA和ECDSA指的是用来签名握手中server key exchange中传过来的秘密值的签名算法。
3.2.2从密码套件的各个部分去分析其安全性,具体如下:
(1)密钥交换:ECDHE,DHE,ECDH,DHE,ADH, RSA, PSK
其中RSA,ECDH,DH,PSK均不具有前向安全性,一旦私钥丢失,则以往所有的通信内容将会泄露,使用前向安全性算法(ECDHE,DHE),可以避免这种问题。
ADH为Anonymous DH,匿名DH算法,不提供身份验证,禁用。
PSK算法是预存key在客户端和服务端,因为PSK必须要预置密钥,这个预置的过程就代表了服务端已经知道有哪些客户端需要访问了,所以基于PSK的TLS适合在内部系统中使用,而不适合在公网环境用来提供Web服务。
综上,推荐使用的密钥交换算法为:ECDHE,DHE
(2)数字签名:ECDSA, RSA(2048位以上), DSS (又称DSA)
其中DSA只支持1024bits,不安全算法,RSA要2048位以上才安全.ECDSA速度较快,安全性也较高.
推荐使用数字签名算法ECDSA和RSA.
(3) 加密算法:DES,3DES ,**AES(256),ChaCha20,RC4, **ChaCha20
3DES运行缓慢且易被攻击。RC4已不安全
ChaCha20是一种流加密算法,实现较为简单,并且比纯软件实现的AES性能更好。
在支持AES指令的硬件平台上,推荐优先选择AES-GCM算法,不支持AES指令的硬件平台,ChaCha20性能优于AES
Camellia算法支持128比特的分组长度,128、192和256比特的密钥与AES的接口相同,Camellia算法128比特密钥的加、解密过程共有18轮,采用Feistel结构,加、解密过程完全相同,只是子密钥注入顺序相反
Camellia算法由NTT和Mitsubishi Electric Corporation于2000年联合开发,作为欧洲新一代的加密标准。与AES算法相比,Camellia算法在各种软硬件平台上表现出与之相当的加密速度。除了在各种软件和硬件平台上的高效性这一显著特点,它的另外一个特点是针对小规模硬件平台的设计.
推荐使用AES(256),ChaCha20ChaCha20
(4)工作模式:CBC,GCM
CBC 模式密码 —— 易受 BEAST 和 Lucky 13 攻击,禁用
推荐使用:GCM
(5)MAC:md5,SHA-1(又名SHA),SHA-2(又名SHA128,SHA256和SHA384)
SHA1存在碰攻击,如果HTTPS证书使用sha1,扩展存在中间人攻击; Md5也被破解
推荐使用SHA256和SHA384
3.3 优先使用的密码套件
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
REF:
https://cshihong.github.io/2019/05/09/SSL%E5%8D%8F%E8%AE%AE%E8%AF%A6%E8%A7%A3/
https://juejin.im/post/6844903667577929742#heading-12
https://www.jianshu.com/p/cf8c2f2cd18a
https://www.cnblogs.com/zhuqil/archive/2012/10/06/ssl_detail.html