TLS 1.0 RFC http://www.ietf.org/rfc/rfc2246.txt
TLS 1.1 RFC http://www.ietf.org/rfc/rfc4346.txt
TLS 1.2 RFC http://www.ietf.org/rfc/rfc5246.txt
TLS 1.3 见:https://blog.youkuaiyun.com/mrpre/article/details/81532469
这里根据TLS
的实现,进行总结。至于各个版本号之间丢弃了哪些算法、新增了哪些算法,直接看RFC
即可,这里并不关心。
这里只关心TLS
报文内在处理逻辑存在哪些变化,即站在代码的角度剖析。各位看官如果对TLS
协议不熟悉,那么不建议看此文章。要读懂此文章需要对TLS
实现由较深的理解,想了解TLS
基础知识,建议从本系列开头看起。
区别1:对finished
报文(Encrypted handshake message
)影响
TLS 1.0
TLS 1.1
在计算finish
时,进行的是MD5+ SHA1
组合方式运算,而在TLS 1.2下
,摘要算法变成了单次SHA256
。
伪代码如下
If(version >= TLS1_2)
{
If (cipher.mac == SHA384)
{
restult = SHA384(handshake_in );
}
Else
{
restult = SHA256(handshake_in);
}
}
Else
{
restult = md5(handshake_in) + sha1(handshake_in);
}
其中 handshake_in
是 字符串常量+所有握手信息(类型为Handshake
的message
)。
例如
作为client
端handshake_in =“client finidhed” + all_handshake
作为Server
端handshake_in = “server finidhed” + all_handshake
注:对于加密套件存在SHA384
及其以上的高级摘要算法,无论TLS
哪个版本,都用 加密套件指定的 握手摘要算法计算 摘要,如上伪代码所示(RFC上说对于每一种新的算法, 都需要指定default
还是SHAXXX
,但是在实现上,都是根据MAC
是什么,SHAXXX
就是什么)。
其实加密套件中指定的摘要算法是用来在加密时进行HMAC
的,并不影响握手流程中的运算,但是如果两端协商的加密套件支持SHAXXX
,那么必然表示两端支持SHAXXX
算法,那么在SHAXXX
安全性高于SHA256
的情况下,握手阶段需要摘要算法就没必要那么‘死’只用SHA256
。当然目前也没有比SHA384
更高的了。
区别2:对PRF
算法的影响
先用伪代码梳理逻辑:
If(version >= TLS1_2)
{
If (cipher.mac == SHA384)
{
TLS1_2_PRF(SHA384, in, srcret);
}
Else
{
TLS1_2_PRF(SHA256, in, srcret);
}
}
Else
{
TLS1_PRF(MD5,SHA1, in, srcret);
}
1:对于SHA384
的判断,上面已经说过,这里不再赘述。
2:可以看到TLS1.2
和TLS 1.0
TLS 1.1
的PRF
实现也不同,参数不同。
TLS 1.2 的PRF
单次P_HASH
,P_HASH
使用的是SHA256
TLS 1.1 的PRF
两次P_HASH
,第一次P_HASH
使用的是MD5
,以及secret
的前半部分;第二次P_HASH
使用的SHA1
,以及secret
的后半部分。两次P_HASH
的结果进行亦或(xor
),得到最后结果。
注意secret
如果是偶数,则正好各一半,如果是奇数:
例如secret
是1234567,则前一半 指的是1234,后一半指的是4567,中间一个字节公用。
区别3:对Certificate verify
的影响
Certificate vertify
是客户端在发送证书后,为了表明自己是证书的拥有者,用自己的私钥对之前收到、发送的握手信息进行签名。(和finished
类似)。
同样签名前,需要对握手信息进行HASH
运算。
TLS1.0 TLS1.1:
使用MD5+SHA1
的形式对握手信息进行摘要运算,这个流程和计算finished
一样,只是不加字符串常量’XXX finished
’。
注:有一个例外,对于ECDSA
签名算法(客户端证书是ECC
证书),只做单次SHA1
计算。
TLS 1.2:
TLS 1.2 下, certificate verify
报文格式和之前的不同,多出2个字节(Signature Hash Algorithm
),表示hash_alg
以及sign_alg
。具体握手摘要根据hash_alg
进行单次计算。
同样,如果加密套件存在SHA384,则使用SHA384
TLS 1.2下 Certificate verify
的格式
伪代码如下:
If(version >= TLS1_2)
{
result = SHAXXX(all_handshake);
ADD_MD_INFO_TO_PACKET();//报文中增加两个字节表明自己签名算法
}
Else
{
If(ECDSA_SIGN)
{
result = SHA1(all_handshake);
}
Else
{
result = MD5(all_handshake) + SHA1(all_handshake)
}
}
总结来说:
1:TLS 1.2需要增加2个字节表明签名算法类型(非对称+摘要)。而TLS1.2之前的协议默认就用md5+sha1
的形式计算摘要,非对称算法肯定使用私钥类型对应的算法,这个无需显示表明。
2:ECDSA
签名需要特殊对待。
区别4:对server key exchange
的影响
TLS1.2下和 certificate verify
类似,报文格式较之前版本有不同。多了2个字节表示HASH
算法和签名算法。
签名时的摘要逻辑和certificate verify
一样。
区别5:对加密的影响
这个变化是TLS1.1开始变化的,不是TLS1.2。
为了对抗beast
攻击,SSL
在加密数据前,需要填充一个BLOCK_SIZE
(IV_SIZE
)长度的随机数,这个随机值也被作为数据的一部分进行加密,在解密时,同样进行解密,然后丢弃。
CBC
下,对于上述这个场景我们其实可以进行优化,这个BLOCK_SIZE
的数据对于发送端来说可以不进行加密,然后下一个数据块的Write_IV
改成这个随机数,这样CBC
模式就可以完整的工作。对于解密方来说,这个BLOCK_SIZE
的数据可以不解密,然后解密下一个块时的Read_IV
变成这个随机数,CBC
模式也能正常工作。减少了一个BLOCK_SIZE
的解密、加密数据。