闲话HTTPS
前言
大家在浏览网页的时候一定有这样的体验,有一些网站在网址那里会显示一个绿色的挂锁,并且网址中“https”相关的字样也是绿色的,聪明的朋友肯定会问,这些颜色和符号代表什么意思呢?想想大家在上网的时候,经常要输入账号和密码,有时候网购还要输入信用卡信息,如果这些信息被偷了,后果是很严重的。是的,这个绿色的锁就是用来保护大家的信息不被黑客窃取。
现在很多网站默认使用HTTPS来保护用户的信息,截止2018年4月,Alexa前100万的网站中,32.2%使用HTTPS作为默认设置,互联网最受欢迎的137971个网站中,57.1%使用了HTTPS;Firefox遥测数据显示,70%的网站使用了HTTPS。
HTTPS是什么
HTTPS安全(HTTPS)是超文本传输协议(HTTP)的扩展,它能够使计算机网络进行安全通信,现已广泛用于Internet。
HTTPS使用传输层安全协议(TLS)或其前身安全套接层(SSL)对通信进行加密。所以HTTPS有时也被称为HTTP over TLS或者HTTP over SSL。服务端和客户端仍然使用HTTP协议进行通信,在通信过程中通过安全的连接来加密和解密他们的请求和响应。HTTPS主要做了两件事:
- 对访问的网站进行身份验证
- 传输过程中保护交换数据的隐私和完整性
客户端和服务端之间使用了双向加密,可以防止窃听和篡改数据。这样在一定程度上保证了用户浏览网页时不会被冒名顶替者欺骗。
最开始的时候,HTTPS主要用于保护万维网上的支付行为,电子邮件和公司信息系统中的敏感交易。后面随着大家安全意识的增强,网站普遍开启了HTTPS,用于保护网页的真实性,账户安全,并保持用户通信,身份和网页浏览的私密性。
安全连接
客户端和服务端的SSL/TLS连接通过握手建立,建立安全连接的目的在于:
- 保护通信的隐私和完整。通过加密通信,确保没有任何第三方能够读取或篡改客户端与服务器交换的数据。
- 身份鉴定。通过使用非对称加密技术,SSL/TLS能让通信双方识别对方的身份。也就是说,双方都知道他们正在与谁通信。在网络交易中,这尤其重要,因为我们需要确保资金转给了能确认身份的人
- 完全正向保密(PFS)。简单的说,PFS的主要工作是确保在服务器私钥遭到入侵的情况下,攻击者无法解密任何先前的TLS通信。通过使用Diffie-Hellman临时密钥交换可以实现PFS,该交换为每个会话提供新的密钥,密钥只在会话的生命周期中生效。
握手流程
握手的流程如下:
大致可以分为三个阶段
-
Hello阶段。握手从客户端发送ClientHello消息开始。
-
Client Hello,发送下面的内容:
- client_version:客户端支持的SSL/TLS版本
- random:一个32字节的随机数,其中4个字节是客户端当前时间戳。
- session_id:连接会话ID,如果不为空,服务器将搜索缓存的会话,并在找到匹配的情况下恢复会话。
- compression_methods:压缩数据包的方式。使用压缩可以提高传输速度。
- cipher_suites:使用的加密算法的组合,用来衡量连接的总体安全性。
-
Server Hello,发送下面的内容:
- server_version:服务端从客户端支持的SSL/TLS版本中选出一个
- random:一个32字节的随机数,其中4个字节是服务端当前时间戳。
- session_id:会话id。如果不为空,服务端会搜索缓存中的会话,如果找到则恢复会话。如果为空,一个新的会话将会被创建。
- compression_methods:如果支持,服务器将统一使用客户端的首选压缩方法。
- cipher_suites:如果支持,服务器将同意客户的首选密码套件。
下面是Server Hello的一个例子:
-
-
交换证书阶段
- Certificate:服务端发送签名证书和公钥,向客户端证明自己。
- Client Certificate(可选):服务端有时候也可能要求客户端证明自己。此时客户端将自己的签名证书提供给服务端
下面是Certificate的一个例子:
-
密钥交换阶段:
- Server Key Exchange:仅当服务端提供的证书不足以允许客户端交换预主密钥时,服务端才会发送交换密钥信息
- Server Hello Done:服务端确认Hello消息完成。
下面是用Server Key Exchange和Server Hello Done的例子
- Client Key Exchange。在接收到服务端Hello Done后,客户端发送Client Key Exchange给服务端。如果服务端请求客户端证书,客户端要在发送证书后在发送Key Exchange。在这个阶段中,客户端将创建一个预主密钥。
- Pre-Master Secret:预主密钥由客户端创建,创建后与服务端共享。在共享前,客户端使用服务端公钥对其进行加密。这样只有服务端可以解密该消息。
- Master Secret:服务端收到预主密钥后,将使用其私钥对其进行解密。现在。客户端和服务端都更具之前交换的随机值计算主密钥。计算的伪代码如下,其中PRF是用来生成伪随机数据的函数
master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random) [0..47];
- Change Cipher-Spec:此时,客户端和服务端都可以切换到安全的机密环境。 Change Cipher Spec协议用于通知彼此可以使用新的加密方法了。
下面是一个抓包例子
握手过程的最后一条消息和安全连接中的第一条加密消息是Finished,下下面是一个例子。
证书
信任
从形式上看,SSL/TLS证书只是一个文本文件而已,任何用于文本编辑器的人都可以创建一个证书。利用一些现有的工具可以轻易创建一个证书来声明自己是谷歌,并且控制着域名gmail.com。如果真的能这样的话,SSL/TLS将成为一个笑话。身份验证流程是:
- 客户端问“你是Google吗?”
- 服务器回答“呃,这还用问吗,你看,这里有张纸,上面写着‘我是Google’”
- 客户说“好的,这是我的数据。”
防止这种闹剧的办法在于数字签名,它允许一方验证另一方的纸张是否合法。
有两个情况让用户可以信任一个证书:
- 这个证书在用户信任的证书列表中
- 这个证书能够证明自己被控制上述列表的证书控制器所信任。
第一种情况很简单。浏览器都会预先安装来自证书颁发机构(CA)的可信SSL证书列表。用户可以查看,添加,删除这些证书。在实际情况中,这些证书会由赛门铁克,Comodo和GoDaddy等非常安全,可靠指的信赖的组织来颁发。
符合第二种情况更难一些。服务器很容易说:“呃,我的名字是,呃微软,你信任赛门铁克,呃他们完全信任我,所以你懂得。”有点聪明的客户可能去问赛门铁克:“我这里有一个叫微软的说你相信他们,这是真的吗?”不过,即使赛门铁克说“是的,我们知道微软,他是可信的”,你仍然不知道这个号称是微软的服务器真的是微软呢,还是其他更糟糕的东西。这就是我们需要数字签名的原因。
数字签名
之前提到过,SSL/TLS证书有用到公钥/私钥对。公钥作为证书的一部分被公开,而私钥需要很好的保护。这对非对称密钥在SSL握手中用于交换双方的另一个密钥来对数据进行加密和解密,即客户端使用服务器的公钥来加密对称密钥并将其安全地发送到服务器,然后服务器使用其私钥对其进行解密。任何人都可以使用公钥进行加密,但只有服务器可以使用私钥进行解密。
而数字签名的使用正好相反。证书由一个权威机构“签署”,权威机构在证书上记录“我们已经证实此证书的控制者拥有对证书上列出的域名具有控制权”,记录的方式是,授权机构使用他们的私钥对证书的内容进行加密,并将该密文附加到证书上作其数字签名。任何人都可以使用授权机构的公钥解密这个签名进行验证。因为只有授权机构才能使用私钥加密内容,所以只有授权机构能够真正创建一个有效的签名。
因此,如果服务器声称拥有由赛门铁克签署的Microsoft.com的证书,浏览不必相信它。如果用赛门铁克的公钥能够证明证书上的签名是有效的话,那么这个证书就是合法的。赛门铁克会采取措施确保他们签署的组织确实拥有Microsoft.com域名,如果客户端信任赛门铁克,那么也可以信任服务属于Microsoft公司。
自签名
值得注意的是,所有根CA证书都是“自签名的”,也就是说数字证书是使用CA自己的私钥生成的。和其他证书相比,CA证书没有什么特殊的地方。你完全可以生成自己的自签名证书,并根据需要使用此证书来签署其他证书。只不过你的证书并没有作为CA预先加载到其他人的浏览器里,其他人都不会相信你你签署证书或者其他证书。如果你胆敢宣称“我是微软,这是我自己签发和签署的官方证书”,所有的浏览器都会因为这个错误的凭证抛出一个非常可怕的错误信息。。
这些安全措施要由浏览器和操作系统发行商来处理,他们只信任干净的根CA,那些组织是他们的用户最终信任审查网站并保证证书安全的组织。
防范攻击
技术上,用户并不需要验证是否应该信任发送证书的一方,而是应该信任证书中包含的公钥。SSL证书是完全公开和公开的,因此任何攻击者都可以获取Microsoft的证书,拦截客户对Microsoft.com的请求并向其提供合法证书。客户会接受证书并地开始握手。但是,当客户端加密将用于实际数据加密的密钥时,它将使用真实证书中获得的Microsoft的公钥进行加密。由于攻击者没有微软的私钥来解密,通信无法进行进行。即使握手完成,他们仍然无法解密密钥,因此无法解密客户端发送给他们的任何数据。只要攻击者不控制可信证书的私钥,数据就无法被解密。如果攻击者用某种方式让客户相信了假冒的证书和公钥,还是会产生问题。
一些有意思的事情
咖啡店可以通过他们的网络监控HTTPS流量吗?
并不能。公钥密码术的神奇在于攻击者可以嗅探客户端和服务器之间交换的每一个字节的数据,但是并不能获取这些数据里的信息。在不安全的WI-FI网络上浏览HTTP的网站是非常危险的。举个例子,用户使用HTTPS提交用户名/密码组合的表单,但假如这个表单是通过HTTP加载的,攻击者可能会在表单HTML中插入恶意代码,将账号/密码发送到他们自己的服务器上。
公司可以通过他们的网络监视HTTPS流量吗?
如果公司控制着你用的电脑,那么是的。每一个信任链的根源在于隐含信任的CA,并且这些权限的列表存储在浏览器中。公司可以将自己的自签名证书添加到电脑的CA列表中。因为浏览器信任其伪造的签名,因此公司可以提供声称代表相应网站的证书,来拦截你所有的HTTPS请求。由于客户端将使用其恶意证书的公钥对所有HTTPS请求进行加密,因此他们可以使用相应的私钥解密并检查(甚至修改)请求,然后将其发送到其预期的位置。
公司是由这个能力的,取决于他们想不想这样干。
结语
HTTPS不是不可破解的,并且SSL/TLS协议必须随着新攻击被发现和压制而不断发展。不过在很多情况下,它能够保证足够的安全性。关键点在于,虽然HTTPS可以保证数据安全地到达目的地,但是它并不能保护用户免受XSS攻击,重放攻击,数据库泄漏的威胁。它正如电影中《黑衣人》的主题曲:“Walk in shadow, move in silence, guard against extra-terrestrial violence(行于阴影,行于沉默,打击暴力和恐怖
)”