HTTPS的原理浅析与本地开发实践(上)

371次阅读  |  发布于2年以前

本文提出了HTTP协议在目前网络传输中存在的问题,然后基于两个典型问题做了合理的方案设想,最终推演出的第四种方案。

本文为专题第一篇,9月28日推送专题第二篇,敬请关注。

日常的开发过程中本地环境保持登录状态是前置条件,在校园B端业务模块的日常研发过程中,一般先通过预发环境登录,将登录态保存在taobao.com的domain下,然后在本地通过Vite/Webpack Server + Nginx + host的方式构造自定义域名(一级域名与登录态的domain一致),进而做下一步的开发工作。但是目前预发/生产的域名都是https协议,本地自定义的域名默认协议是http。因此,为了读取登录态信息,需要将本地的访问地址也配置成https协议。实现的过程主要是在本地通过OpenSSL工具按照x509证书标准生成自签证书,并将这个自签证书添加到电脑的证书配置项中即可(具体操作过程可以关注明天的推送)。这个配置过程引起了我对数字证书与HTTPS协议关系的好奇,因此做了下面的原理探究,下面就对这个探究的过程就一下记录,浅析HTTPS的实现原理,并将两种配置证书的方式的具体操作步骤做了记录。

关键词

加密算法、数字签名、秘钥交换、Wireshark、OpenSSL

引言

首先就需要抛出一个问题,为什么HTTP协议的网址越来越少?我们可以通过下面这个典型的HTTP数据传输流程看出它的问题 —— 即数据在Client/Server之间不加识别的明文传输。 (www.ccdoit.com-http1.1-only.pcapng)

明文传输和匿名发送对象也体现了互联网信息不可靠的典型特性:

  1. 篡改数据(伪造) —— 破坏数据一致性;
  2. 嗅探(偷窥) —— 破坏数据的安全性;

问题解法

—— 如果想解决http的这两个问题,我们需要如何改良它?

方案一:通过对称加密的方式传输数据

场景一:客户端与服务端交互,通过约定的对称秘钥加密传输数据,在前端资源加载时,仍然可以从数据中找出想要的秘钥;

场景二:客户端/服务端交互如果临时生成随机秘钥,在传输过程中仍然有被截获的风险;

问题:秘钥在网络中传输容易被拦截,假设秘钥泄露,密文全会被破解且无法确定发送方是否安全;

方案二:通过非对称加密的方式传输数据

场景:服务端产生秘钥对,公钥交给客户端,私钥自己保存,不会在互联网传输,安全性更高;

问题:

  1. 由于公钥是公开的,中间人可以篡改上行或者下行内容。该方案能解决上行数据安全性(密文传输,无法破解)问题,但是无法解决下行数据的安全性问题(公开的公钥可以解密服务端返回的密文)。此外,数据一致性问题业务法保证,因为中间人可以假借公钥加密自己的数据给服务端,可以修改上行数据,或者中间人告知客户端的公钥为自己的秘钥对,进行修改下行数据。
  2. 非对称加密的效率偏低,不适合用于数据传输;

方案 三:先客户端/服务端间通过非对称加密协商秘钥,然后用协商的秘钥做后续的数据传输

场景:先客户端/服务端双方通过约定的某种秘钥协商算法在客户端计算出秘钥K,并通过公钥加密K传输给服务端,服务端通过私钥解密后,开始基于秘钥K做数据的对称加密传输。

问题:

  1. 固定的秘钥对和网络中传输的秘钥存在被窃取的可能,安全性并不牢固;
  2. 客户端/服务端在数据传输前没有做合法性校验,无法避免中间人攻击;

方案四:先在客户端/服务端之间做认证,然后通过非对称加密协商秘钥,最后用协商的秘钥做后续的数据传输

场景:在传输数据前先通过鉴别通信双方是否真实,而不是假冒的其他用户,在身份验证完毕后,基于某种高安全性的秘钥协商算法,通过非对称加密(秘钥对随机产生)的方式在客户端/服务端之间协商秘钥,双方会基于协商算法的公开数据得到相同的秘钥,然后开启后续的对称加密通信。

特点:

  1. 数据传输前先做身份认证,基本可以解决中间人攻击的问题,防止篡改数据;
  2. 使用高安全性的秘钥加密通信数据,可以有效防止数据被嗅探;

结论

方案四就是HTTPS解决明文传输两大问题的基本思路。其中身份认证涉及数字签名和数字证书概念,而非对称加密设计非对称加密体系。由于非对称加密的计算性能不及对称加密,所以,在经过几轮握手,协商好秘钥后,将数据传输的加密方式改为对称加密。

总的来说,HTTPS就是通过数字证书 + 非对称秘钥体系 + 对称秘钥体系的组合方案来解决HTTP协议传输明文的两大问题。

HTTPS

HTTPS (Hypertext Transfer Protocol Secure) 是基于 HTTP 的扩展,用于计算机网络的安全通信,已经在互联网得到广泛应用。在 HTTPS 中,原有的 HTTP 协议会得到 TLS (Transport Layer Security - 安全传输层协议) 或其前任 SSL (Secure Sockets Layer - 安全套接层) 的加密。因此 HTTPS 也常指 HTTP over TLS 或 HTTP over SSL。(HTTPS)

理论分析

方案四只对信息传输的场景做了简要分析,其中有数字签名、数字证书、加密体系这些基础概念,为了方便在后续解析TLS/SSL握手过程,这里先对涉及的基础技术概念做简要的汇总介绍。

散列函数 —— 散列算法、哈希函数

散列函数(Hash Function)是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来(散列值)。

  1. 确定性:如果两个散列值是不相同的(根据同一散列函数),那么这两个散列值的原始输入也是不相同的;
  2. 不可逆性:故意创建产生给定散列值的消息是不可行的;
  3. 散列碰撞:散列函数的输入和输出不是唯一对应关系的,如果两个散列值相同,两个输入值很可能是相同的,但也可能不同;
  1. MD (Message Digest)摘要算法:MD算法生成的摘要消息都是128位长(32位的十六进制数字)表示,安全性排序:MD2 < MD4 < MD5,但是目前安全性最高的MD5算法存在弱点,可以被破解。
  2. SHA(Secure Hash Algorithm)安全散列

数据加密 数据加密是指将明文信息改变为难以读取的密文内容,使之不可读的过程。只有拥有解密方法的对象,经由解密过程,才能将密文还原为正常可读的内容。基于加解密秘钥是否相同的特点,可以分为对称加密和非对称加密。

特点

加密和解密密钥是相同的。通信方必须具有相同的密钥才能实现安全通信。 图片来源:什么是SSL?https://www.cloudflare.com/zh-cn/learning/ssl/how-does-ssl-work/

常见算法分类
  1. DES(Data Encryption Standard):数据加密标准
  2. 3DES/3DEA(Triple Data Encryption Algorithm):三重数据加密算法
  3. AES(Advanced Encryption Standard):高级加密标准
特点
  1. 加密和解密的秘钥不同,加密密钥(公钥)供任何人使用和加密消息。但是,只有接收方才能访问能够通过解密密钥(私钥)读取消息;
  2. 对于同一个秘钥对,公钥加密后,可以用私钥解密,反之亦然;

图片来源:什么是SSL?https://www.cloudflare.com/zh-cn/learning/ssl/how-does-ssl-work/

常见算法分类

非对称 + 对称加密

数据“加密”小结

数字签名(公钥数字签名)

只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。数字签名算法一般使用 RSA(非对称加密) + SHA256(安全摘要算法)。

解决了文件在发送过程中无法被篡改的问题,但是无法避免被中间人伪造。

RSA加密过程通式

,公钥 = (e,n)

RSA解密过程通式

,私钥 = (d,n)

秘钥对为 (e,d,n);

小明用自己的秘钥对生成签名过程:待签名的数据 => 哈希运算(SHA-256) => 文件哈希值(摘要) => 签名运算(RSA,私钥加密) => 数字签名;

小红拥有小明对外开发的公钥(PS:小红可能不知道,小明的公钥已经被替换成中间人的公钥),在收到小明的信息后,做签名验证;

公钥解密后的哈希值与待签名的文件哈希值对比,相同,则签名成立,否则签名不成立。

小明传输的数字签名可以被另外一个具有秘钥对的中间人替换传输的文件。相当于中间人模仿了小明的“签名”。

这个问题出现的核心原因在于:小明的公钥被中间人的公钥替换了,小红自己无法判断当前的公钥是否是小明的!所以,我们需要证明的是接收方拿到的公钥是发送方提供的,而不是中间人提供的。

基于当前的案例,我们如何证明小红接收到的公钥就是小明发送的,而非被他人篡改的呢?这就需要有一种公开的权威的认证机制 ——数字证书机制。

数字证书是利用非对称秘钥体系中,秘钥对的公钥和私钥是一一对应的特性,通过权威的证书签发机构(CA)签发证书预制秘钥,并将根证书预装在操作系统中,从而防止公钥被篡改。所以,数字证书可以用来证明公钥是属于某个认证用户的。

证书签发机构用自己的私钥对需要认证的人(或组织机构)的公钥施加数字签名并生成证书,即证书的本质就是对公钥施加数字签名。

  1. 产生终端证书:将发送方提供的身份信息和公钥信息作为基础数据,CA基于这些数据做哈希和数字签名(CA的私钥加密)操作产生数字证书;
  2. 证书合法性校验:发送方会将CA签发的终端证书通过互联网发送给接收方,接收方会基于CA预装在系统内的根证书(含CA公钥)来验证发送方提供的整证书是否合法;

这种在数据传输过程中引入第三方来证明公钥的合法性是相对安全的,因为被信任的CA根证书都会被预装在操作系统中,这就相当于信任自己的操作系统,所以HTTPS协议在整个传输过程中,数据的一致性和安全性可以得到有效的保证。

任何解决方案都不是银弹,都存在弱点或者不足。基于CA证书的通信过程也不是完美无缺的,因为CA机构本身也可能存在管理上的问题,进而导致伪造证书泛滥,被有心者恶意利用,或者用户本身安全意识淡薄导致将不安全的证书安装进操作系统,导致数据传输安全问题的发生。(案例:《distrusting-new-cnnic-certificates》https://blog.mozilla.org/security/2015/04/02/distrusting-new-cnnic-certificates/)

HTTP的数据交换流程

下面会基于wireshark工具,对单次HTTPS协议的网站流量进行详细的分析。 HTTP和HTTPS数据交换流程对比

基于DH秘钥协商算法的信息交换流程

HTTPS数据传输步骤分解

  1. TCP握手 —— 建立链接;
  2. TLS握手或者秘钥协商过程(基于TLS版本的不同或者缓存影响,握手次数有所差异,这里只看TLSv1.2的标准流程),握手目的:验证身份、交换信息、生成秘钥,为后续的通信做准备,总览图如下:

(mac-https-ssl.ccdoit.com no ico TLS use curl.pcapng) 3. TCP挥手 —— 断开链接;

TLS握手过程简析> TCP建立链接和断开链接不是本次关注的重点,这里只对TLS握手协商秘钥的过程做一个简要的分析。

C端代表客户端,S端代表服务端



【C端 -> S端】 —— 告知S端,当前C端支持的协议版本(Version)、加密通信支持套件(Cipher Suites)等信息,并产生了一个随机数(5a882b)。

【S端 ->C端】 —— 告知C端,确定使用TLS协议版本号是1.2、生成的随机数(524401)、产生会话ID、确定加密通信的套件为TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384。

通信套件(Cipher Suite)解析:

  1. 生成秘钥:密钥协商算法使用ECDHE ;
  2. 数据传输加密算法:握手后的通信使用 AES 对称算法,密钥长度 256位,分组模式是 GCM;
  3. 身份验证:签名算法使用RSA;
  4. 完整性校验:摘要算法使用SHA384;

TLS 的会话缓存机制 —— SessionId(协议标准字段) 和 Session Ticket(协议扩展字段),后续篇幅研究;



【S端 -> C端】

第一步:发送证书 —— Certificate:服务器向客户端验证身份;

第二步:完成证书验证后,开始基于ECDHE做秘钥协商:公开椭圆曲线 Curve25519—— 蒙哥马利曲线( )和曲线基点G(值为9)、S端随机产生私钥d1(存在本地)、通过私钥d1和基点G生成公钥Q1(Pubkey)。携带签名算法防止篡改公钥。

常见的三种秘钥协商过程简析:

‍客户端连上服务端;服务端发送 CA 证书给客户端; 客户端验证该证书的合法性; 客户端从 CA 证书中取出公钥P;客户端生成一个随机密钥 K,并用这个公钥加密得到 K';客户端把K' 发送给服务端;服务端收到 K’ 后用自己的私钥S解密得到 K; 此时双方都得到了密钥 K,协商完成;

双方开始使用秘钥K进行加密通信;

RSA的协商方式存在的问题是,加密数据在C和S端传输,如果S端的私钥泄密,则会导致加密传输的数据都会被破解,是否有更好的方式,能让对称加密的秘钥不在网络间传输,而是由双方通过统一的规则来在各自的环境内计算得到?这就是需要用到下面的DH算法来优化当前这个传输的过程。- 基于DH的秘钥协商(依靠秘钥交换算法)

客户端先连上服务端;

服务端生成一个随机数 s 作为自己的私钥,然后根据算法参数计算出公钥 S(算法参数通常是固定的);

服务端使用某种签名算法把“算法参数(模数P,基数G)和服务端公钥S”作为一个整体进行签名;

服务端把“算法参数(模数P,基数G)、服务端公钥S、签名”发送给客户端;

客户端收到后验证签名是否有效;

客户端生成一个随机数 c 作为自己的私钥,然后根据算法参数计算出公钥 C;

客户端把 C 发送给服务端;

客户端和服务端(根据上述 DH 算法)各自计算出 K 作为会话密钥;

DH协商秘钥协商算法计算性能不佳,因为协商过程中双方都需要做大量的乘法运算,为了提升 DHE算法的性能,所以就出现了现在广泛用于密钥交换算法 —— ECDHE算法。

ECDHE 算法是在 DHE 算法的基础上利用了 ECC 椭圆曲线特性,可以用更少的计算量计算出公钥,以及最终的会话密钥。

小红和小明使用 ECDHE 密钥交换算法的过程:

  1. 双方事先确定好使用的椭圆曲线类型以及曲线上的基点 G,这两个参数都是公开的,一般采用密码学中比较著名的椭圆曲线函数,例如本次会话用到的Curve25519曲线;
  2. 双方各自随机生成一个随机数作为私钥d,并与基点 G相乘得到公钥Q(Q = dG),此时小红的公私钥为 Q1 和 d1,小明的公私钥为 Q2 和 d2;
  3. 双方交换各自的公钥Q1和Q2;
  4. 通过椭圆曲线特性计算得到相同的x坐标作为协商秘钥K,过程如下:

小红计算点

小明计算点

基于椭圆曲线的特性 d1Q2 = d1d2G = d2d1G = d2Q1 ,因此双方的 x 坐标 是相等的,所以它是共享密钥,也就是会话密钥。(详细的数学原理 :https://www.cnblogs.com/kalafinaian/p/7392505.html)

这个过程中,双方的私钥都是随机、临时生成的,都是不公开的,即使根据公开的信息(椭圆曲线、公钥、基点 G)也是很难计算出椭圆曲线上的离散对数(私钥)。

第三步:Server Hello done,S端已经完成向C端的消息发送;

【C端 -> S端】

  1. 客户端在本地随机生成一个私钥d2,通过私钥d2和基点G生成公钥Q2(Pubkey)。此时,双方都有对方的椭圆曲线公钥、自己的椭圆曲线私钥、椭圆曲线基点 G。于是,双方都就计算出点(x,y),其中 x 坐标值双方都是一样的。x直接作为对称加密的秘钥使用安全性低,双方为了会提高秘钥的安全性,会在x上“加盐”处理,即使用先前会话产生的随机数组合产生秘钥 —— 【5a882b + 524401 + x 】。
  2. 秘钥协商完毕,告知S端后续通信数据改用对称算法加密;
  3. 对数据做摘要算法,使用秘钥加密,交给服务端验证;

【S端 -> C端】

  1. 确认改用对称加密算法加密后续的通信数据;
  2. 使用同样的方式传输加密后的数据并交给客户端验证。



TLS 经过五次握手协商并得到加密秘钥后,双方就开始基于对称加密的方式对传输数据,这样能很好的提高数据传输的效率。

数据传输(加密)

通信双方使用“加盐”后的秘钥加密数据,并在网络间传输。如果传输中获取到秘钥协商时产生的秘钥,则可以解密已经加密的 Application Data,例如,TLSv1.3 的加密数据被wireshark解密。

(https-ssl.ccdoit.com-no ico-WITH FIN TCP.pcapng)

小结

文章的最开始就提出了HTTP协议在目前网络传输中存在的问题,然后基于两个典型问题做了合理的方案设想,最终推演出的第四种方案是更趋近于两个问题的实际解决方案的。在提出方案后,开始对其中涉及到的哈希函数、数据加密、数字签名等书面概念做了简单的总结,目的是为后续HTTPS的实际秘钥协商过程和数据传输过程做了铺垫。随后,基于wireshark工具,拦截一次HTTPS请求流量,对TLS(1.2版本)的秘钥协商过程(握手过程)做了相对细致的分析,期间也对先前TLS版本使用的秘钥协商过程做了简要的介绍,希望能够帮助你在理解HTTPS协议概念上能有所帮助。

下一篇文章属于实战部分,将重点介绍HTTPS证书的配置过程,我将会以阿里云证书配置和OpenSSL自签证书配置两种方式来让你的网站从HTTP转换到HTTPS。

概念汇总

概念 名称 解释
TLS(Transport Layer Security)/SSL(Secure Sockets Layer) 传输层安全协议/安全套阶层 ---
OpenSSL —— Cryptography and SSL/TLS Toolkit openssl是一个功能丰富且自包含的开源安全工具箱 它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证书验证、PKCS7标准实现和PKCS12个人数字证书格式实现等功能。
Message Digest 信息摘要 也称特征值,它是将一段很长的数据信息,通过hash函数(MD5 或 sha 1等)计算,得到一串长度“较短”且“定长”的短数值,来作为这段数据独一无二的特征值。该过程不可逆。
Digital Signature 数字签名 使用用户的私钥(private key)对信息摘要进行加密,生成的信息。私钥 + 信息摘要 = 数字签名。
Digital Certificate 数字证书 由某个被信任的机构(CA)签发、认证用户身份的数字文件。CA私钥 + 认证用户的基础信息 + 认证用户的公钥 = 数字证书
CRT/CER( Certificate) 证书 经权威授权机构数字签名,包含公开密钥的拥有者信息以及公开密钥的文件,是权威机构颁发给网站的可信凭证。最简单的证书包含一个公开密钥、证书名称以及证书授权中心的数字签名。CRT常见于Linux系统,内容常用PEM,也有DER编码,CER常见于Windows系统,内容常用DER编码,也有PEM编码。
X.509 证书标准 定义证书中需要包含的内容 —— https://www.ietf.org/rfc/rfc5280.txt
PEM( Privacy Enhanced Mail) X.509证书的编码格式 文本格式,以"-----BEGIN..."开头, "-----END..."结尾,内容是BASE64编码。 PEM转为DER :openssl x509 -in cert.crt -outform der -out cert.der
CER( Distinguished Encoding Rules) X.509证书的编码格式 二进制格式,不可读。 DER转为PEM :openssl x509 -in cert.crt -inform der -outform pem -out cert.pem
CA( Certificate Authority) 数字证书颁发机构/证书授权中心 CA认证中心作为电子商务交易中受信任的第三方,承担公钥体系中公钥合法性检验的责任。
CSR( Certificate Signing Request) 证书签名请求 它包含了您的服务器信息和公司信息。申请证书时需要将您证书的CSR文件提交给CA认证中心审核,CA中心对CSR文件进行根证书私钥签名后会生成证书公钥文件(即签发给您的SSL证书)
KEY 存放私钥或者公钥的文件 ---
SAN( Subject Alternative Names) --- 可以使用一个数字证书绑定多个通用名称(即使互不相关的名称)。参加上面的手动创建CSR

参考资料

  1. https://www.cloudflare.com/zh-cn/learning/ssl/keyless-ssl/
  2. https://www.cloudflare.com/zh-cn/learning/ssl/how-does-ssl-work/
  3. https://www.ssl.com/zh-CN/常见问题/什么是x-509证书/#
  4. https://www.cloudflare.com/zh-cn/learning/ssl/keyless-ssl/
  5. https://zh.wikipedia.org/wiki/Curve25519
  6. https://zh.wikipedia.org/wiki/SHA家族
  7. https://zh.wikipedia.org/wiki/橢圓曲線迪菲-赫爾曼金鑰交換

附件

  1. HTTP数据传输过程文件
  2. HTTPS秘钥协商&数据传输过程文件
  3. 解密HTTPS传输数据的文件

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8