详解https加密通信原理

对https是怎么样加密数据的,一直都不是太了解,在此深入了一下。

加密算法

对称加密

这是我们加密文件常用的方式,加密的时候输入一个密码,解密的时候也用这个密码,加密和解密都用同一个密码,所以叫对称加密。常见的算法有DES(Data Encryption Standard)、AES(Advanced Encryption Standard)、RC4、IDEA。对称安全性不仅取决于加密算法本身,密钥管理的安全性更是重要。因为加密和解密都使用同一个密钥,如何把密钥安全地传递到解密者手上就成了必须要解决的问题。

非对称加密

非对称加密是一个很神奇的东西,它有两个不一样的密码,一个叫私钥,另一个叫公钥,私钥加密后的密文,只要是公钥,都可以解密,但是公钥加密后的密文,只有私钥可以解密。私钥只有一个人有,而公钥可以发给所有的人

私钥一般自己保存,而公钥是公开的,同等加密强度下,非对称加密算法的速度比不上对称加密算法的速度,所以非对称加密一般用于数字签名和密码(对称加密算法的密码)的交换。常见的算法有RSA、DSA、ECC。

非对称加密相比对称加密更加安全,但也存在两个致命的缺点:

(1)CPU计算资源消耗非常大。一次完全TLS握手,密钥交换时的非对称解密计算量占整个握手过程的90%以上。而对称加密的计算量只相当于非对称加密的0.1%。如果后续的应用层数据传输过程也使用非对称加解密,那么CPU性能开销太庞大,服务器是根本无法承受的。赛门特克给出的实验数据显示,加解密同等数量的文件,非对称算法消耗的CPU资源是对称算法的1000倍以上。

(2)非对称加密算法对加密内容的长度有限制,不能超过公钥长度。比如现在常用的公钥长度是2048位,意味着待加密内容不能超过256个字节。

非对称加解密(极端消耗CPU资源)目前只能用来作对称密钥交换或者CA签名,不适合用来做应用层内容传输的加解密。

摘要算法

数字摘要是采用单项Hash函数将需要加密的明文“摘要”成一串固定长度(128位)的密文,这一串密文又称为数字指纹,它有固定的长度,而且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。“数字摘要“是https能确保数据完整性和防篡改的根本原因。常见的算法有CRC、MD5、SHA1、SHA256。

数字签名

数字签名就是“非对称加密+摘要算法”,注意,不是数字证书,其目的不是为了加密,而是用来防止他人篡改数据。

其核心思想是:比如A要给B发送数据,A先用摘要算法得到数据的指纹,然后用A的私钥加密指纹,加密后的指纹就是A的签名;B收到数据和A的签名后,也用同样的摘要算法计算指纹,然后用A公开的公钥解密签名,比较两个指纹,如果相同,说明数据没有被篡改,确实是A发过来的数据。假设C想改A发给B的数据来欺骗B,因为篡改数据后指纹会变,要想跟A的签名里面的指纹一致,就得改签名,但由于没有A的私钥,所以改不了,如果C用自己的私钥生成一个新的签名,B收到数据后用A的公钥根本就解不开。

  • 数字签名的过程如下:明文 --> hash运算 --> 摘要 --> 私钥加密 --> 数字签名
  • 数字签名验证的过程如下:数字签名 --> 公钥解密 --> 摘要 --> hash原文 --> 对比摘要

数字证书

服务器首先生成公私钥,将公钥提供给相关机构(CA),CA将公钥放入数字证书并将数字证书颁布给服务器,此时服务器就不是简单的把公钥给客户端,而是给客户端一个数字证书,数字证书中加入了一些数字签名的机制,保证了数字证书一定是服务器给客户端的

服务器在给客户端传输公钥的过程中,会把公钥以及服务器的个人信息通过Hash算法生成信息摘要。如图

为了防止信息摘要被人调换,服务器还会用CA提供的私钥对信息摘要进行加密来形成数字签名。如图:

并且,最后还会把原来没Hash算法之前的个人信息以及公钥 和 数字签名合并在一起,形成数字证书。如图

当客户端拿到这份数字证书之后,就会用CA提供的公钥来对数字证书里面的数字签名进行解密来得到信息摘要,然后对数字证书里服务器的公钥以及个人信息进行Hash得到另外一份信息摘要。最后把两份信息摘要进行对比,如果一样,则证明这个人是服务器,否则就不是。如图:

这样,就可以保证服务器的公钥安全着交给客户端了。

版权声明:本文为CSDN博主「帅地」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_37907797/article/details/102759257

图解HTTPS

这节主要说明了https加密方法来源,这一部分主要参考了 https://github.com/youngwind/blog/issues/108 ,太清晰明了了。

  1. http的交互:

img

  1. http通信不安全,那就密码进行通信:

  1. 想法非常好,数据是通过加密了,但是这个密码要怎么传输呢?聪明的人类就想出了非对称加密的方法,即client使用服务器提供的公钥加密数据,server收到数据之后就使用自己的私钥解密数据。注意,这里说的数据不是真正的数据,而是会话密钥,就是解决了第二点的问题。这样client和server就得到了密码,那就使用这个会话密钥去加密真正的数据了。

    img

  2. 看上去第三步已经解决了密钥传输的问题,但是如果有被人截持了,那这样就直接裸奔了,如下图:

    img

    此问题的关键点是client收到公钥之后,没办法验证这个公钥是不是假的。

  3. 这东西这么不靠谱,那要怎么办呢?那就再加一层:使用数字证书来保证数据的准确性。下图的1~5步,是需要网站管理人员要去申请一个https证书,然后部署到服务器上面。当client收到server发的证书之后,会对证书进行验证是否有效。

    img

  4. 有了数字证书之后,中间人想要来截持是不可能的了,但是charles是可以解密Https数据包,这是为什么呢?charles之所以能劫持,并不是因为 HTTPS 不安全,而是因为操作人主动安装信任了 Charles 根证书中心。

TLS握手过程

使用随机数,就是使用随机数来生成对称加密算法。这样就可以做到服务器和客户端每次交互都是新的加密算法、只有在交互的那一刻才确定加密算法。

TLS主要包含两部分协议,一部分是Record Protocol,描述了数据的格式,另一部分是Handshaking Protocols,描述了握手过程。

握手的目的有两个,一个是保证通信的双方都是自己期待的对方,任何一方都不可能被冒充,另一个是交换加密密码,使得只有通信的双方知道这个密码,而别人不知道。前一个就是我们常说的认证,而后一个就是密码交换。认证是通过证书来达到的,而密码交换是通过证书里面的非对称加密算法(公私钥)来实现的。

服务器首先生成公私钥,将公钥提供给相关机构(CA),CA将公钥放入数字证书并将数字证书颁布给服务器,此时服务器就不是简单的把公钥给客户端,而是给客户端一个数字证书,数字证书中加入了一些数字签名的机制,保证了数字证书一定是服务器给客户端的。中间人发送的伪造证书,不能够获得CA的认证,此时,客户端和服务器就知道通信被劫持了。

注意点:

(1)数字签名签发和校验使用的非对称密钥是CA自己的公钥和私钥,跟证书申请者(提交证书申请的公司实体)提交的公钥没有任何关系。

(2)数字签名的签发过程跟公钥加密的过程刚好相反,即是用私钥加密,公钥解密。(一对公钥和私钥,公钥加密的内容只有私钥能够解密;反过来,私钥加密的内容,也就有公钥才能够解密)

(3)现在大的CA都会有证书链,证书链的好处:首先是安全,保持CA的私钥离线使用。第二个好处是方便部署和撤销。这里为啥要撤销呢?因为,如果CA数字证书出现问题(被篡改或者污染),只需要撤销相应级别的证书,根证书依然是安全的。

(4)根CA证书都是自签名,即用自己的公钥和私钥完成了签名的制作和验证。而证书链上的证书签名都是使用上一级证书的非对称密钥进行签名和验证的。

(5)怎样获取根CA和多级CA的密钥对?还有,既然是自签名和自认证,那么它们是否安全可信?这里的答案是:当然可信,因为这些厂商跟浏览器和操作系统都有合作,它们的根公钥都默认装到了浏览器或者操作系统环境里。

实际交互过程

img

  1. ClientHello

    client向server发起请求,client会告诉server支持的TLS版本号、支持的密码套件、随机数(用于后续的密钥的生成)、session id等,相关信息如下:

    • 支持的最高TSL协议版本version,从低到高依次 SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2,当前基本不再使用低于 TLSv1 的版本;
    • 客户端支持的加密套件 cipher suites 列表, 每个加密套件对应前面 TLS 原理中的四个功能的组合:认证算法 Au (身份验证)、密钥交换算法 KeyExchange(密钥协商)、对称加密算法 Enc (信息加密)和信息摘要 Mac(完整性校验);
    • 支持的压缩算法 compression methods 列表,用于后续的信息压缩传输;
    • 随机数 random_C,用于后续的密钥的生成;
    • 扩展字段 extensions,支持协议与算法的相关参数以及其它辅助信息等,常见的 SNI 就属于扩展字段,后续单独讨论该字段作用。
  2. server_hello+server_certificate+sever_hello_done

    • server_hello, 服务端返回协商的信息结果,包括选择使用的协议版本 version,选择的加密套件 cipher suite,选择的压缩算法 compression method、随机数 random_S 等,其中随机数用于后续的密钥协商;
    • server_certificates, 服务器端配置对应的证书链,用于身份验证与密钥交换;
    • server_hello_done,通知客户端 server_hello 信息发送结束;
  3. 证书校验

    客户端需要验证证书的合法性,如果验证通过才会进行后续通信,否则根据错误情况不同做出提示和操作,合法性验证包括如下:

    • 证书链的可信性 trusted certificate path,方法如前文所述;
    • 证书是否吊销 revocation,有两类方式离线 CRL 与在线 OCSP,不同的客户端行为会不同;
    • 有效期 expiry date,证书是否在有效时间范围;
    • 域名 domain,核查证书域名是否与当前的访问域名匹配,匹配规则后续分析;
  4. client_key_exchange+change_cipher_spec+encrypted_handshake_message

    • client_key_exchange,合法性验证通过之后,客户端计算产生随机数字 Pre-master,并用证书公钥加密,发送给服务器;
    • 此时客户端已经获取全部的计算协商密钥需要的信息:两个明文随机数 random_C 和 random_S 与自己计算产生的 Pre-master,计算得到协商密钥;enc_key=Fuc(random_C, random_S, Pre-Master)
    • change_cipher_spec,客户端通知服务器后续的通信都采用协商的通信密钥和加密算法进行加密通信;
    • encrypted_handshake_message,结合之前所有通信参数的 hash 值与其它相关信息生成一段数据,采用协商密钥 session secret 与算法进行加密,然后发送给服务器用于数据与握手验证;
  5. change_cipher_spec+encrypted_handshake_message

    • 服务器用私钥解密加密的 Pre-master 数据,基于之前交换的两个明文随机数 random_C 和 random_S,计算得到协商密钥:enc_key=Fuc(random_C, random_S, Pre-Master);
    • 计算之前所有接收信息的 hash 值,然后解密客户端发送的 encrypted_handshake_message,验证数据和密钥正确性;
    • change_cipher_spec, 验证通过之后,服务器同样发送 change_cipher_spec 以告知客户端后续的通信都采用协商的密钥与算法进行加密通信;
    • encrypted_handshake_message, 服务器也结合所有当前的通信参数信息生成一段数据并采用协商密钥 session secret 与算法加密并发送到客户端;
  6. 握手结束

参考实际的抓包图如下:

各阶段的详细含义:

  • Client Hello
    • 客户端发送的,属于TLS握手协议(TLS handshake)的一部分,其内容包括客户端的一个Unix时间戳(GMT Unix Time)、一些随机的字节(Random Bytes),还包括了客户端接受的算法类型(Cipher Suites),本例中Mozilla Firefox 57.0允许15种算法,浏览器认为这些算法是可以被信任的。这是最基本的部分,同时还有其他的扩展参数,这里就不做介绍了。
    • Client Hello的目的就类似于SYN,客户端对服务器公布自己支持的算法等等,同时也附带请求服务器证书的意思。这里不验证客户端证书,所以Client Hello就只有这些内容。
  • Server Hello
    • 服务器发送的,同样属于TLS handshake,内容包括服务器的GMT Unix Time以及Random Bytes,和上面类似就不再解释。这时候服务器会将自己支持的算法类型发送给客户端,以便于客户端进行验证,这里我的服务器使用的是TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,也就是使用AES-128的GCM模式进行对称加密,同时以带SHA-256的RSA作为签名算法,用ECDHE做密钥交换的一整套协议。我的服务器也算是主流安全啦~
    • Server Hello目的就是服务器对客户端公布自己的算法,以便于后续操作。
  • Certificate
    • 服务器或者客户端发送的,依旧属于TLS handshake,它一般和Server Hello在同一个TCP报文中传送。显然的,这里服务器将自己的数字证书发送给客户端,客户端就会进行证书验证,如果不通过的话,客户端会中断握手的过程。如果也要求客户端提供证书的话,Client Hello后面也会紧跟着该报文,形式完全一样,就不再解释了。
  • Server Key Exchange
    • 服务器发送的,属于TLS handshake,一般也和Server Hello与Certificate在一个TCP报文中。服务器将自己的公钥参数传输给了客户端,因为使用的是ECDHE,这里传输的内容有:椭圆曲线域参数,以及公钥的值。
    • 这个就是密钥交换协议的一部分,最终协商出密钥来。
  • Server Hello Done:服务器发送的,属于TLS handshake,一般也和Server Hello、Certificate和Server Key Exchange在一个TCP报文中,介于Server Hello和Server Hello之间的是服务器想要给客户端的东西。所以这里面客户端没有发送Client Hello Done
  • Client Key Exchange:客户端发送的,属于TLS handshake,客户端收到了服务器的证书进行验证,如果验证通过了,就会继续密钥交换的过程,向服务器发送自己的公钥参数。待服务器收到之后进行数学计算,就可以协商出密钥了,这里客户端实际上已经计算出了密钥。
  • Change Cipher Spec:客户端或者服务器发送的,属于TLS handshake,紧跟着Key Exchange发送,代表自己生成了新的密钥,通知对方以后将更换密钥,使用新的密钥进行通信。
  • Encrypted Handshake Message:客户端或者服务器发送的,属于TLS handshake,也是紧跟着Key Exchange发送。这里是进行一下测试,一方用自己的刚刚生成的密钥加密一段固定的消息发送给对方,如果密钥协商正确无误的话,对方应该可以解密。这段加密内容的明文一般是协议中规定好的,双方都知道。
  • New Session Ticket:服务器发送的,属于TLS handshake,服务器给客户端一个会话,用处就是在一段时间之内(超时时间到来之前),双方都以刚刚交换的密钥进行通信。从这以后,加密通信正式开始。
  • Application Data:应用层的数据,是加密的,使用密钥交换协议协商出来的密钥加密。因为我们的Wireshark不知道服务器的私钥,所以这段通信是安全的,我们在Wireshark中也无法解密这段信息。
  • Encrypted Alert:客户端或服务器发送的,意味着加密通信因为某些原因需要中断,警告对方不要再发送敏感的数据。

结语:HTTPS要使客户端与服务器端的通信过程得到安全保证,必须使用的对称加密算法,但是协商对称加密算法的过程,需要使用非对称加密算法来保证安全,然而直接使用非对称加密的过程本身也不安全,会有中间人篡改公钥的可能性,所以客户端与服务器不直接使用公钥,而是使用数字证书签发机构CA颁发的证书来保证非对称加密过程本身的安全。这样通过这些机制协商出一个对称加密算法,就此双方使用该算法进行加密解密。从而解决了客户端与服务器端之间的通信安全问题。

注意:服务器在给客户端传输公钥的过程中,会把公钥以及服务器的个人信息通过Hash算法生成信息摘要,其目的就是为了保证数据是真实服务器发送的。

参考资料

也许,这样理解HTTPS更容易

图解 HTTPS:Charles 捕获 HTTPS 的原理

HTTPS协议详解(四):TLS/SSL握手过程

GoLang:你真的了解 HTTPS 吗?

什么是 https ?这应该是全网把 https 讲的最好的一篇文章了

  • 本文作者: wumingx
  • 本文链接: https://www.wumingx.com/tcpip/https-theory.html
  • 本文主题: 详解https加密通信原理
  • 版权声明: 本站所有文章除特别声明外,转载请注明出处!如有侵权,请联系我删除。
0%