HTTPS原理以及GOLANG指定HTTPS密码套件

文章来源

最近跟菊厂合做,我司向他们提供SAAS服务。但因为他们对服务安全管控比较严格,内部有专门部门去审核上线的服务。所以菊厂派人来我司专门对安全这块作全面排查,期间加了很多班。其中他们提到了对HTTPS密码套件作配置,当初只知道HTTPS握手后须要非对称加密的算法,后面查询了才知道原来还有这一系列的通信过程当中使用的密码算法。特此写下文章做为学习记录。html

HTTPS简介

HTTPS是Hyper Text Transfer Protocol Secure的缩写。是一个计算机系统间进行安全通讯的协议,主要用在浏览器和web服务器之间进行通讯。HTTP使用明文进行数据传输,而HTTPS则使用加密数据进行传输
HTTPS能够有效防止黑客在浏览器和web服务器之间窃取和修改数据,即便黑客获取到这些数据,因为数据已经被加密,对黑客来讲实际上是垃圾数据。
HTTPS使用SSL(Secure Socket Layer)或者TLS(Transport Layer Security)协议来创建起浏览器和web服务器之间的加密链接。golang

握手过程

  1. 客户端给出协议版本号、生成的 随机数Client random,以及客户端支持的加密方法。
  2. 服务端确认双方使用的加密方法,并给出数字证书、以及一个 服务器生成的随机数Server random
  3. 客户端确认数字证书有效,而后生成一个新的 随机数Premaster secret,并使用数字证书中的公钥,加密这个随机数,发给服务端。
  4. 服务端使用本身的私钥,解析获取客户端发来的随机数Premaster secret

上述能够归结为三次通讯,但即便上并不止三次,归结为下图。
服务端和客户端据约定的加密方法,使用前面的三个随机数,生成 对话密钥session key。服务器和客户端将会使用该密码进行对称加密,保证通讯过程当中信息的安全。web

image.png算法

CA证书认证流程

在服务端发送CA证书给客户端后,客户端须要进行一系列的验证。浏览器

CA证书简介

CA证书其实就是第三方机构,做用是检查证书持有者身份的合法性,并签发证书,以防证书被伪造或篡改。咱们都知道CA证书是用来验证网站的安全性,其实,证书除了能够用来验证某个网站,还能够用来验证某个文件是否被篡改。
因为证书所涉及面太宽广,里面涉及到如何签发、格式规范等。本文不作过多涉及。安全

证书内容

  • 证书颁发机构的名称
  • 证书自己的数字签名
  • 证书持有者公钥
  • 证书签名用到的Hash算法
  • ...

认证流程

  1. 首先浏览器读取证书中的证书全部者、有效期等信息进行一一校验。浏览器开始查找操做系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发
  2. 若是找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。
  3. 若是找到,那么浏览器就会从操做系统中取出颁发者CA 的公钥,而后对服务器发来的证书里面的数字签名进行解密
  4. 浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名作对比
  5. 对比结果一致,则证实服务器发来的证书合法,没有被冒充
  6. 此时浏览器就能够读取证书中的公钥,用于后续加密了

image (1).png

密码学套件

简介

密码套件分为三大部分:密钥交换算法,数据加密算法,消息验证算法(MAC,message authentication code)。密钥交换算法用于握手过程当中创建信道,通常采用非对称加密算法。数据加密算法用于信道创建以后的加密传输数据,通常采用对称加密算法。MAC顾名思义是一种哈希,用于验证消息的完整性,包括整个握手流程的完整性(例如TLS握手的最后一步就是一个对已有的握手消息的全盘哈希计算的过程)。服务器

获取本机支持套件

#openssl ciphers -V
image (2).png网络

密码套件名详解

TLS_DHE_RSA_WITH_AES_256_CBC_SHA是一个密码学套件的标准名字。
这里的TLS表明的是TLS协议,若是将来TLS更名,这个名字可能会变,不然会一直是这个名字。WITH是一个分隔单次,WITH前面的表示的是握手过程所使用的非对称加密方法,WITH后面的表示的是加密信道的对称加密方法和用于数据完整性检查的哈希方法。WITH前面一般有两个单次,第一个单次是约定密钥交换的协议,第二个单次是约定证书的验证算法。两个功能都须要使用非对称加密算法。交换信息使用的非对称加密算法是第一个单词,证书使用的非对称加密算法是第二个。
有的证书套件,例如TLS_RSA_WITH_AES_256_CBC_SHA,WITH单词前面只有一个RSA单词,这时就表示交换算法和证书算法都是使用的RSA,因此只指定一次便可。可选的主要的密钥交换算法包括: RSA, DH, ECDH, ECDHE。可选的主要的证书算法包括:RSA, DSA, ECDSA。二者能够独立选择,并不冲突。AES_256_CBC指的是AES这种对称加密算法的256位算法的CBC模式,AES自己是一类对称加密算法的统称,实际的使用时要指定位数和计算模式,CBC就是一种基于块的计算模式。最后一个SHA就是代码计算一个消息完整性的哈希算法。session

握手过程详解

image (3).png

客户端发出请求
ClientHello
因为客户端(如浏览器)对一些加解密算法的支持程度不同,可是在TLS协议传输过程当中必须使用同一套加解密算法才能保证数据可以正常的加解密。在TLS握手阶段,客户端首先要告知服务端,本身支持哪些加密算法,因此客户端须要将本地支持的加密套件(Cipher Suite)的列表传送给服务端。除此以外,客户端还要产生一个随机数,这个随机数一方面须要在客户端保存,另外一方面须要传送给服务端,客户端的随机数须要跟服务端产生的随机数结合起来产生后面要讲到的 Master Secret 。
综上,在这一步,客户端主要向服务器提供如下信息:dom

  • 支持的协议版本,好比TLS 1.0版
  • 一个客户端生成的随机数,稍后用于生成"对话密钥"
  • 支持的加密方法,好比RSA公钥加密
  • 支持的压缩方法

服务器回应
SeverHello
上图中,从Server Hello到Server Done,有些服务端的实现是每条单独发送,有服务端实现是合并到一块儿发送。Sever Hello和Server Done都是只有头没有内容的数据。
服务端在接收到客户端的Client Hello以后,服务端须要将本身的证书发送给客户端。这个证书是对于服务端的一种认证。例如,客户端收到了一个来自于称本身是www.alipay.com的数据,可是如何证实对方是合法的alipay支付宝呢?这就是证书的做用,支付宝的证书能够证实它是alipay,而不是财付通。证书是须要申请,并由专门的数字证书认证机构(CA)经过很是严格的审核以后颁发的电子证书。颁发证书的同时会产生一个私钥和公钥。私钥由服务端本身保存,不可泄漏。公钥则是附带在证书的信息中,能够公开的。证书自己也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,能够防止证书被串改。另外,证书还有个有效期。
Server Key Exchange(证书公钥发送)
在服务端向客户端发送的证书中没有提供足够的信息(证书公钥)的时候,还能够向客户端发送一个Server Key Exchange。
Cerficate Request(请求客户端证书)
此外,对于很是重要的保密数据,服务端还须要对客户端进行验证,以保证数据传送给了安全的合法的客户端。服务端能够向客户端发出 Cerficate Request 消息,要求客户端发送证书对客户端的合法性进行验证。好比,金融机构每每只容许认证客户连入本身的网络,就会向正式客户提供USB密钥,里面就包含了一张客户端证书。
跟客户端同样,服务端也须要产生一个随机数发送给客户端。客户端和服务端都须要使用这两个随机数来产生PreMaster Secret
最后服务端会发送一个Server Hello Done消息给客户端,表示Server Hello消息结束了。
综上,在这一步,服务器的回应包含如下内容:

  • 确认使用的加密通讯协议版本,好比TLS 1.0版本。若是浏览器与服务器支持的版本不一致,服务器关闭加密通讯
  • 一个服务器生成的随机数,稍后用于生成"对话密钥"
  • 确认使用的加密方法,好比RSA公钥加密
  • 服务器证书

客户端回应
Client Key Exchange(发送客户端证书)
若是服务端须要对客户端进行验证,在客户端收到服务端的 Server Hello 消息以后,首先须要向服务端发送客户端的证书,让服务端来验证客户端的合法性。
Certificate Verify(证书检查)接着,客户端须要对服务端的证书进行检查,若是证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已通过期,就会向访问者显示一个警告,由其选择是否还要继续通讯。若是证书没有问题,客户端就会从服务器证书中取出服务器的公钥。而后,向服务器发送下面三项信息:
一个随机数。该随机数用服务器公钥加密,防止被窃听
编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送
客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的全部内容的hash值,用来供服务器校验
上面第一项的随机数,是整个握手阶段出现的第三个随机数,它是客户端使用一些加密算法(例如:RSA, Diffie-Hellman)产生一个48个字节的Key,这个Key叫 PreMaster Secret
ChangeCipherSpecChangeCipherSpec
一个独立的协议,体如今数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到以前协商好的加密套件(Cipher Suite)的状态,准备使用以前协商好的加密套件加密数据并传输了。
在ChangecipherSpec传输完毕以后,客户端会使用以前协商好的加密套件和Session Secret加密一段 Finish 的数据传送给服务端,此数据是为了在正式传输应用数据以前对刚刚握手创建起来的加解密通道进行验证。
服务器的最后回应
Server Finish
服务端在接收到客户端传过来的 PreMaster 加密数据以后,使用私钥对这段加密数据进行解密,并对数据进行验证,也会使用跟客户端一样的方式生成 Session Secret,一切准备好以后,会给客户端发送一个 ChangeCipherSpec,告知客户端已经切换到协商过的加密套件状态,准备使用加密套件和 Session Secret加密数据了。以后,服务端也会使用 Session Secret 加密一段 Finish 消息发送给客户端,以验证以前经过握手创建起来的加解密通道是否成功。
根据以前的握手信息,若是客户端和服务端都能对Finish信息进行正常加解密且消息正确的被验证,则说明握手通道已经创建成功,接下来,双方可使用上面产生的Session Secret对数据进行加密传输了。

golang中配置ssl

tlsconf := &tls.Config{
        InsecureSkipVerify:       true,
        MaxVersion:               tls.VersionTLS13,
        MinVersion:               tls.VersionTLS12,
        PreferServerCipherSuites: true,
}
tlsconf.CipherSuites = []uint16{
        tls.TLS_AES_128_GCM_SHA256,
        tls.TLS_CHACHA20_POLY1305_SHA256,
        tls.TLS_AES_256_GCM_SHA384,
        tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
        tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
        tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
        tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
        tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
        tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
        tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
        tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
        tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
        tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
        tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
        tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
}

参考文章

https://blog.csdn.net/zhangta...
https://zhuanlan.zhihu.com/p/...
http://blog.chinaunix.net/uid...

相关文章
相关标签/搜索