本文提出了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)
明文传输和匿名发送对象也体现了互联网信息不可靠的典型特性:
—— 如果想解决http的这两个问题,我们需要如何改良它?
▐ 方案一:通过对称加密的方式传输数据
场景一:客户端与服务端交互,通过约定的对称秘钥加密传输数据,在前端资源加载时,仍然可以从数据中找出想要的秘钥;
场景二:客户端/服务端交互如果临时生成随机秘钥,在传输过程中仍然有被截获的风险;
问题:秘钥在网络中传输容易被拦截,假设秘钥泄露,密文全会被破解且无法确定发送方是否安全;
▐ 方案二:通过非对称加密的方式传输数据
场景:服务端产生秘钥对,公钥交给客户端,私钥自己保存,不会在互联网传输,安全性更高;
问题:
▐ 方案 三:先客户端/服务端间通过非对称加密协商秘钥,然后用协商的秘钥做后续的数据传输
场景:先客户端/服务端双方通过约定的某种秘钥协商算法在客户端计算出秘钥K,并通过公钥加密K传输给服务端,服务端通过私钥解密后,开始基于秘钥K做数据的对称加密传输。
问题:
▐ 方案四:先在客户端/服务端之间做认证,然后通过非对称加密协商秘钥,最后用协商的秘钥做后续的数据传输
场景:在传输数据前先通过鉴别通信双方是否真实,而不是假冒的其他用户,在身份验证完毕后,基于某种高安全性的秘钥协商算法,通过非对称加密(秘钥对随机产生)的方式在客户端/服务端之间协商秘钥,双方会基于协商算法的公开数据得到相同的秘钥,然后开启后续的对称加密通信。
特点:
▐ 结论
方案四就是HTTPS解决明文传输两大问题的基本思路。其中身份认证涉及数字签名和数字证书概念,而非对称加密设计非对称加密体系。由于非对称加密的计算性能不及对称加密,所以,在经过几轮握手,协商好秘钥后,将数据传输的加密方式改为对称加密。
总的来说,HTTPS就是通过数字证书 + 非对称秘钥体系 + 对称秘钥体系的组合方案来解决HTTP协议传输明文的两大问题。
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)是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来(散列值)。
▐ 数据加密 数据加密是指将明文信息改变为难以读取的密文内容,使之不可读的过程。只有拥有解密方法的对象,经由解密过程,才能将密文还原为正常可读的内容。基于加解密秘钥是否相同的特点,可以分为对称加密和非对称加密。
加密和解密密钥是相同的。通信方必须具有相同的密钥才能实现安全通信。 图片来源:什么是SSL?https://www.cloudflare.com/zh-cn/learning/ssl/how-does-ssl-work/
图片来源:什么是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)签发证书预制秘钥,并将根证书预装在操作系统中,从而防止公钥被篡改。所以,数字证书可以用来证明公钥是属于某个认证用户的。
证书签发机构用自己的私钥对需要认证的人(或组织机构)的公钥施加数字签名并生成证书,即证书的本质就是对公钥施加数字签名。
这种在数据传输过程中引入第三方来证明公钥的合法性是相对安全的,因为被信任的CA根证书都会被预装在操作系统中,这就相当于信任自己的操作系统,所以HTTPS协议在整个传输过程中,数据的一致性和安全性可以得到有效的保证。
任何解决方案都不是银弹,都存在弱点或者不足。基于CA证书的通信过程也不是完美无缺的,因为CA机构本身也可能存在管理上的问题,进而导致伪造证书泛滥,被有心者恶意利用,或者用户本身安全意识淡薄导致将不安全的证书安装进操作系统,导致数据传输安全问题的发生。(案例:《distrusting-new-cnnic-certificates》https://blog.mozilla.org/security/2015/04/02/distrusting-new-cnnic-certificates/)
下面会基于wireshark工具,对单次HTTPS协议的网站流量进行详细的分析。▐ HTTP和HTTPS数据交换流程对比
基于DH秘钥协商算法的信息交换流程
▐ HTTPS数据传输步骤分解
(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)解析:
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 密钥交换算法的过程:
小红计算点
小明计算点
基于椭圆曲线的特性 d1Q2 = d1d2G = d2d1G = d2Q1 ,因此双方的 x 坐标 是相等的,所以它是共享密钥,也就是会话密钥。(详细的数学原理 :https://www.cnblogs.com/kalafinaian/p/7392505.html)
这个过程中,双方的私钥都是随机、临时生成的,都是不公开的,即使根据公开的信息(椭圆曲线、公钥、基点 G)也是很难计算出椭圆曲线上的离散对数(私钥)。
第三步:Server Hello done,S端已经完成向C端的消息发送;
【C端 -> S端】
【S端 -> C端】
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 |
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8