Https两三事
来源:想说话的朱同学     阅读:561
北京的店
发布于 2018-08-26 23:03
查看主页

今天我们的某条业务线终于用上了HTTPS。 由于实在是忍受不了某动,某通等经营商的内容劫持。不但会嵌入广告, 而且会嵌入少量js代码,导致整个web都崩溃掉。在这个过程中也比较深入的理解了一下HTTPS协议。这里做一个记录。

实际上HTTPS我个人了解起来就是 HTTP over TLS(transport layer security), 因而本篇文章的重点也就是TLS的协议。 我们将重点分析TLS是如何建立起来的,以及https 的 hack 方法。

Https两三事

Https两三事

少量基础姿势

RSA

关于RSA加密相信每一个搞计算机的人可能都理解过(但弄明白的很少吧, 数学的东西推导起来头都大了)。非对称加密,故名思意也就是使用公钥来加密的,使用私钥来解密 。这也是我一开始对于RSA的认知。然而也听说过RSA可以使用做签名, 使用私钥签名使用公钥来验证签名。对于这一点我感到非常的迷惑。How it works? 原来使用私钥加密的内容,可以使用公钥来解密。公钥和私钥的称谓可能本身具备肯定的迷惑性,然而他们本身没有什么本质的区别,使用一把钥匙加密,使用另一把钥匙解密,这是个双向的。

RSA的证实太过复杂,我们也不做赘述。这里只说两个结论

  • 加密过程: 使用公钥来加密后得到密文,使用私钥可以解出平文
  • 签名过程: 使用平文生成一个摘要,使用密钥加密这个摘要。 验签过程就是使用公钥解密摘要并重新使用取得的平文生成摘要进行比照。(之所以不加密整个的平文,可能就是出于性能考虑吧,反正公钥是发布出去的,其实加密了每个人仍旧能得到)

另外非对称加密的方式也不只有RSA一种,比方后面我们提到的Diffie–Hellman也是一种非对称的加密的方式,这种加密方式在密钥交换的过程(key exchange)中还蛮有做使用呢。

Https两三事

数字证书(Digital Certificate)

一个小小的故事

密码学有三个名人 Alice, Bob和 Eve。 我们仍然使用他们三个来讲故事。

  1. Bob要给Alice发送一条信息, 为了证实这条信息是自己发的(没有被伪造 Authentication,没有被篡改 Integrity) 他将这条信息进行了签名并把签名和消息一起发给了Alice
  2. 拥有Bob公钥的Alice 得到这个消息和签名后 通过验证签名能否正确 确定这条消息的确是Bob发的 而且没有被篡改。
  3. 邪恶的Eve想伪造Bob,有一天他偷偷的潜入了Alice的电脑,并把Bob的公钥换成了自己的。物理攻击
  4. 这时Eve即可以假装成Bob给Alice发消息, 并附带上一个使用自己私钥加密后的摘要做签名。由于Alice还不知道Bob的公钥已经被换了,所以验证签名的过程会通过。 这时候Alice已经傻傻分不清Bob和Eve了。

这个问题说明只有公私钥对还是处理不了问题的。我们需要一个方法来保证公钥不会被篡改。又是一个Authentication(Ensure the users of the network are who they say they are) 的问题。 假如信任一个人,需要信任他的公钥, 然而如何做到公钥是可信的?(这里出现了肥皂距离的狗血剧情,既然你不相信我, 那你去问你信任的人好了。问一问他我说的是不是真的。)

Https两三事

后来Bob找到了Alice信任的人 — 一个叫CA的机构。 这个机构比较权威比较出名, 大家都知道他的公钥(由于所有人都知道所以没办法伪造)。 CA将Bob的公钥和Bob的名字以及其余信息放一个文件中,并使用自己的私钥对这个文件进行签名,同时将签名放在这个文件的结尾,于是一个高大上的证书就生成了。

Alice 拿到 Bob 的证书后,首先使用CA的公钥(这里实际上是一个自签名的根证书) 对Bob的证书进行完整性校验,确保的确是由CA颁发的。而后检查证书里面的信息的确是Bob, 这样 Alice即可以确信证书里面的公钥的确是Bob的公钥, 使用他来验证Bob的信息没有问题。

上面的故事已经很好的解释了什么是数字证书及他的做使用。 我们在详情一下现实世界中的证书

现实世界中的证书

在公共网络中,首先有几个比较知名的大的CA机构比方VerSign他们会颁发根证书self-signed root certificate 我们的浏览器或者者电脑会有一个信任根证书列表默认保存这些我们信任的根证书。 以MAC电脑为例, 默认信任列表长这样

为了保证根证书颁发机构密钥的安全性,他们会很吝啬的用自己的密钥,但是有很多人需要去取得证书,肿么办? 于是CA只好去找几个有资质的机构,为他们颁发中间证书(Intermediate certificate authority),拥有这些中间证书的机构又能为自己信的过的机构颁发中间证书(Intermediate certificate authority) 这样就形成了证书链。

使用户可以向任意一家CA去申请自己的证书。申请下来的证书长这样

可见www.dbbar.net的域名证书是由CA 沃通免费SSL证书G2颁发的。 这个CA机构也有自己的证书长这样

总结起来,现实世界按功能分为三种

  1. 自签名证书 self signed root certificate
  2. 为中间证书机构(intermediate certificate authority) 颁发的证书
  3. 为实际证书用而颁发的证书

证书验证过程

写这篇文章的时候,我一直在想:既然信任链可以延续下去,那我们完全可以申请一个证书而后使用这个证书来颁发其余的证书啊。 这样证书不就不可信了么。

猜想程序对证书的验证过程应该是这样的,首先从根证书到要验证证书的证书链。而后检查除要验证证书证书链以上的所有证书的类型能否是self signed root certificate 或者者 intermediate certificate authority 假如不是,那么这个要验证的证书就验证不通过。

我们只能寄希望于所有的CA都是公开,公平,公正的了。他们会对每一个下级CA进行严格的审查, 以确保CA中不会有坏人。(万一哪天某动或者者某通成了CA就不好说了,他们会直接伪造证书,进行中间人吧。)

HTTPS建立的过程

HTTPS 建立的前几秒主要是完成用户端对服务端的验证Authentication, 通信过程中使用的加密方式,数据校验方式的协商, 通信过程中要用的密钥(master key)的交换等过程。 由于后续的通信是加密的,可以防止监听(Confidentiality) 同时会进行数据的校验以防止内容被篡改(Integrity)

网上有好多详情https的过程的,这里简单给一个时序图,感兴趣的同学可以去深入理解

Https两三事

解释:

  1. Client Hello 这个包中有几个信息
  • Random,这里用户端给服务端发了第一个随机值为了方便我们叫做RandomA
  • Session ID: 假如有的话服务端会决定能否要复使用以前的session 以调过交换密钥的过程
  • Cipher Suites:用户端支持的密码套件
  • Extension: 少量扩展,比方server_name 使用来标记要访问的VHOST以应对一个ip多个VHOST部署的情况。
  1. Server Hello 这个包中返回了几个信息:
  • Random: 这是用户端给服务端的一个随机值我们计做RandomB
  • Cipher Suite 要用的密码套件

如api.dbbar.net返回的Server Hello包长这样

这里可以看到Server端选使用的加密套机是TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(我们将在后文中解释Cipher Suite)

  1. Server Certificate server端把证书发给client端
  2. Server Key Exchange 这一步与选择的加密套件有关, 有的加密套件规定的密钥协商机制需要每次动态的用公钥和私钥。这一步骤传的Key需要使用第3步传递的证书进行签名 如:
  3. 这里又涉及了另一个非对称加密算Difffie-Hellman
  4. ** Server Hello Done **: Server Hello 结束
  5. Client Key Exchange: Client把自己的key发送给用户端, 这一步与选择的加密套件有关系。 总之,经过这一步骤之后用户端与服务端就会有一个共享的第三方不知道的密钥(premaster)。 而后用户端与服务端使用这个密钥经过加密套件商定的密码推导算法推倒出使用于通信的密钥master
  6. Change Cipher Spec从现在开始用户端使用加密的方式与服务端通信
  7. Client Finished Message 用户端握手完成,发送的第一条加密信息
  8. New Session Ticket: 服务端给用户端发送一个ticket, 相当于新的session Id, 使用于建立起来的信复使用。
  9. Change Cipher Spec: 从现在开始服务端使用加密的方式与服务端通信
  10. Server Finished Message: 服务端握手完成

一个比较直观的看ssl建立链接的过程是使用openssl, 执行openssl s_client -debug -connect api.dbbar.net:443 或者者采使用wireshark抓包的方式会看到比较完整的连接建立信息这里不做赘述。

Cipher Suite

前面已经屡次提到了cipher suite 到底什么是cipher suite? wiki上给的答案是 A cipher suite is a named combination of authentication, encryption, message authentication code (MAC) and key exchange algorithms used to negotiate the security settings for a network connection using the Transport Layer Security (TLS) / Secure Sockets Layer (SSL) network protocol. 简单的来说一个加密套件规定了TLS建立连接过程的具体细节如: 如何进行加密,如何产生信息校验码, 如何进行密钥交换。

一个Cipher Suite 比方我们前面提到的TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 定义了具体的密钥交换算法,块加密算法, 信息校验码产生算法, 及具体的密码推导算法 pseudorandom function(PRF) 在这个例子中

  • 密钥交换算法:ECDHE_RSA 定义了用户端与服务端如何进行premaster的传递。
  • 块加密算法:AES_256_CBC 是具体传递信息是使用的块加密方法
  • MAC: 这里使用SHA 的方式进行数据完整性校验
  • Pseudo Random Function(PRF): PRF是TLS1.2 所有的密码推导算法。 这个算法采使用伪随机数的生成的方式,以前面用户端与服务端端传递的RandomA, RandomB, premaster 生成master key, 这个就是后续用户端与服务端通信要用的密钥。使用RandomA, RandomB 来保证密钥的随机性不被任意一端所影响。 由于premaster交换的过程是保密的(第三方监听不到) 所以最终生成的master key也是保密的。

当然TLS协议定议了很多cipher suite, 每一个cipher suite 的安全性也不太一样,对CPU性能的占使用也不太一样。

HTTPS下如何去抓包

HTTPS进行抓包,实际上是进行了一次中间人攻击。 我们需要伪造一个假的证书,并让用户端去信任这个证书。而后用户端与中间人即可以建立起TLS链接。而后中间人再去代理商真正的用户端请求服务端。这样处理问题的方式就是这样的了:

那如何才能伪造假证书呢? 这时我们就需要在用户端安装一个我们知道密钥的根证书并信任它。这样我们就能使用我们的密钥去颁发假的证书。而由于用户端信任了我们的根证书,所以它也会认为我们颁发的假证书是真正的证书, 这样真真假假就傻傻分不清楚了。

关于假证书的问题,记得前几年前goagent还存在的时候曾经报出个0 day 漏洞。由于好多人安装并信任了goagent的证书。并且goagent的证书的密钥是公开的。所以可以中间人攻击https服务。做法就是用goagent的密钥来签名伪造的证书。这样屡试不爽。

我们以BurpSuite为例,验证一下这个思路

HTTPS hacker

step1: 将Burpsuite的自签名证书导入firefox并信任。 step2: 设置firefox代理商到burpsuite

我将使用wareshare抓从firefox到burpsuite的包来分析流量

果然:这里使用了一个我们之前信任的PortSwigger CA 证书签名了api.dbbar.net 域名。这样来实现中间人攻击。验证了之前的猜想

中间人攻防治

可以才使用HTTP Public key Pinning的方式来固定用户端只用哪个证书来达到防治的目的

总结

  1. HTTPS本身还是比较复杂的。通过加密的方式,可以有效的防止中间人攻击,前提是用户端不要随便信任无效的证书。
  2. 面向HTTPS的协议有时需要去抓包分析,常使用的抓包工具如burpsuit charlex支持伪造证书以进行中间人攻击。 采使用这种方式也方便了我们去分析HTTPS协议。
免责声明:本文为用户发表,不代表网站立场,仅供参考,不构成引导等用途。 系统环境 服务器应用
相关推荐
前台面试每日 3+1 —— 第291天
Hippy--腾讯新生的移动跨端开发框架
如何利用HTML5实现音频和视频嵌入的方法
八年的感情最后我们输给了自己
Excel中的SQL运用,非常厉害的一种运用,还不赶快马了!
首页
搜索
订单
购物车
我的