HTTPS 通信中的身份认证机制

2016-03-18 10:44:33 +08:00
 wilddog

作者:王继波 野狗科技运维总监,曾在 360 、 TP-Link 从事网络运维相关工作,在网站性能优化、网络协议研究上经验丰富。

野狗官博: https://blog.wilddog.com/

野狗官网: https://www.wilddog.com/

公众订阅号: wilddogbaas

当你访问一个网站时,有没有想过这个问题:如何保证我的访问能直达目标网站,而没有被中间人攻击和劫持。想要解决这个问题,就得依靠 HTTPS 中的身份认证机制。

HTTPS 的基本概念,我在前面的文章介绍过,可以理解为 HTTP+TLS 。 TLS 协议是 HTTPS 的关键,其设计目标是构建安全的传输层,主要通过数据加密、身份认证、数据完整性来实现,同时还具备高扩展性、兼容性的特点。

本文将介绍 HTTPS 功能中的身份认证,及其工作机制。

X.509v3 证书

X.509 是 PKI 体系中的一个证书标准, PKI 体系将在后面的文章中再介绍。 RFC 文档中有对 X.509 的详细描述[RFC 文档] ( https://tools.ietf.org/html/rfc5280#section-4.1.1.2 ) 。当前野狗官网( https://www.wilddog.com ) 使用的证书格式正是 X.509v3 。

X.509v3 证书由三部分组成:

tbsCertificate 又包含 10 项内容,在 HTTPS 握手过程中以明文方式传输:

SignatureAlgorithm 是指定对 tbsCertificate 签名使用的算法。 SignatureValue 是使用 SignatureAlgorithm 指定的哈希和签名算法对 tbsCertificate 进行哈希和签名后的签名值。

可以使用 Wireshark 抓包查看这些字段信息,结果如下:

如果觉得 wireshark 操作太复杂,也可以在浏览器上点击导航栏 https 小图标查看。

如何进行身份认证?

我们以某用户访问野狗官网为例,分析身份认证的过程(以下过程并非完整 HTTPS 握手过程,只是身份认证相关的过程)。

浏览器向 Server 发送请求; Server 返回野狗官网的 X.509v3 证书,其包含三部分: tbsCertificate 、 SignatureAlgorithm 、 SignatureValue ; 浏览器读取证书中的 tbsCertificate 部分(明文),使用 SignatureAlgorithm 中的散列函数计算得到信息摘要,并利用 tbsCertificate 中的公钥解密 SignatureValue 得到信息摘要,然后对比双方的信息摘要,判断是否一致;如果一致,则成功;如果不一致,则失败。

虽然野狗官网的认证完成,但整个身份认证过程并没有结束,因为还需要认证证书链,这在文章后面将介绍。

身份认证算法

身份认证算法有多种,最常见的是 RSA 。通过 openssl 命令可以查看到:

openssl ciphers – V | column – t

我截取了部分输出结果,其中加密套件是认证、加密、 MAC 、密钥交换、密钥衍生的组合,如 ECDHE-RSA-AES256-GCM-SHA384 , ECDHE 做密钥交换、 RSA 做身份认证、 AES256-GCM 做加密算法、 SHA384 做摘要。

RSA 如何保证安全性

更直接的说:私钥加密、公钥解密,如何保证整个过程的安全。引用维基百科对 RSA 的描述:对极大整数做因素分解难度决定了 RSA 算法的可靠性。换言之,对一极大整数做因数分解愈困难, RSA 算法愈可靠。我们来看下 RSA 的过程:

随机选择两个大的质数 p 和 q , p 不等于 q ,计算 N=pq ; 根据欧拉函数,求得 r=φ(N) = φ(p)φ(q)=(p-1)(q-1); 选择一个小于 r 的整数 e ,使 e 与 r 互质。并求得 e 关于 r 的模反元素 d , ed ≡ 1 (mod r); 将 p 和 q 的记录销毁。 最后得到:(N,e)是公钥,(N,d)是私钥。 使用公钥(N,e)加密明文 m ,得到密文 c me ≡ c (mod N) 使用私钥(N,d)解密密文 c ,得到明文 m cd ≡ m (mod N)

真正安全的保证是 N 不能被分解得到 q 和 p 。实际通信中, N 通常非常大,比如 2 的 2048 次方,这在目前是不能被破解的。

在生成证书时,可以指定 RSA 的密钥长度;证书使用后,在证书信息中也可以查看。

证书信任链机制

实际上,在 HTTPS 通信中, Server 下发给 Client 的不仅仅是对端网站的证书,而是一个证书链。这个证书链是从网站证书开始,逐级往上,到根证书。每个证书都被下个证书的私钥签署,每个证书的 Issuer 就是下个证书的 Subject , root CA 内置在浏览器中,是被浏览器所信任的。

那么为什么会使用证书链?使用证书链的好处有两个: 1.安全, 2.保持 CA 的私钥离线,方便部署和撤销。如果没有证书链,那么当由 CA 来验证网站的证书时,如何保障这个过程中的 CA 是可靠的而不是伪造的。这就是证书链的作用。证书链的顶端是内置在浏览器或操作系统中的 rootCA ,一级一级的信任,保证了最后网站身份的可靠认证。每个证书的证书链往往是多条的,野狗官网证书的证书链有两条。

我们以野狗官网证书的三级证书链为例, wilddog.com 证书 –> Go Daddy Secure Certificate Authority 证书 –> Go Daddy Root Certificate Authority 证书 。浏览器在接收到 wilddog.com 网站的证书链后,首先会对 wilddog.com 网站证书认证:

验证完 wilddog.com 证书后,向上验证中间证书 GoDaddy Secure 证书,过程与之类似;验证完 GoDaddy Secure 证书后,继续验证 GoDaddy Root 证书,因为 GoDaddy Root 证书是自签名的,是浏览器内置的 CA 证书,所以是被浏览器所信任的。 这就是证书的信任链,浏览器信任内置 CA 证书– Go Daddy Root 证书, Go Daddy Root 证书信任 Go Daddy Secure 证书, Go Daddy Secure 证书信任 wilddog.com 证书,所以浏览器信任 wilddog.com 证书。

当然每个浏览器内置的 CA 列表存在差异, Mozilla 的 CA 证书列表: http://mxr.mozilla.org/mozilla-release/source/security/nss/lib/ckfw/builtins/certdata.txt

Go Daddy Root 证书在 Chrome 浏览器内置的 CA 列表中看到。

3000 次点击
所在节点    问与答
4 条回复
3dwelcome
2016-03-18 13:28:31 +08:00
哈,我就是用野狗主页做 CHACHA20_POLY1305 算法测试的。。因为在 V2EX 的 ssl 区域经常看到贵站。

可是加密协议只有老版本的 OLD_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256(0xCC13), 没有新版本的 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256(0xCCA8), 后者可是修复了前者的各种问题,作为标准来替代前者的。

每次测试 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 时,连接 https://www.wilddog.com 总是返回握手失败,不爽!


--------- 最后喷一下 ---------
"RSA 做身份认证、 AES256-GCM 做加密算法、 SHA384 做摘要。"
这句说法不对,在以前的版本里 AES256-CBC-SHA256, 最后 SHA256 确实是指验证加密有没有错误的摘要。但 AES256-GCM 不一样,是新版 HMAC 和加密的合成体产物,不仅仅承担的加密责任,同时也整合了固定 16 字节的校验值,并不是 SHA384 的 384 位校验值。所有新版 AEAD 的加密算法,都自带校验功能。

这里 SHA384 不是摘要,是握手时的协议规范而已。
3dwelcome
2016-03-18 13:40:31 +08:00
<img src="http://dn-cnode.qbox.me/FgDUQB1Uo00fgejQD3OazqQeDng3">

这图中最后的 mac, 才是摘要算法。而不是所谓• TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 里的 SHA256 。
macliu
2016-04-20 00:54:33 +08:00
@3dwelcome 。。。
xl0shk
2016-04-20 21:25:08 +08:00
@3dwelcome
首先感谢你阅读了这篇文章,也感谢指正。
对于使用 OLD_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256(0xCC13),我解释下。
为避免不断被爆出的 OpenSSL 漏洞带来的影响,我们的 SSL 库一直使用 LibreSSL ,但不幸的是, LibreSSL 的 stable 版本一直不支持 chacha20-draft ,只支持 0xcc13 、 0xcc14 、 0xcc15 。
现在我们已经更换 SSL 库为 OpenSSL+Patch ,并已经支持 0xcca8 。
这是我们在 ssllabs dev 上测试结果:
https://dev.ssllabs.com/ssltest/analyze.html?d=www.wilddog.com&hideResults=on
再次感谢。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/264395

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX