[实践]-给你的博客上一把锁

再不https都老了

本文我们来学习下https,然后给自己的博客上一个把锁。说到https,可能有一个问题是大家必问的,那就是为啥要用https,答案很简单: 美啊。 先来一张图观赏下:

其实最重要的还是安全,在这个根本没有隐私的国度里,https显得更加那么的重要。在你网站被运营商 乱插 的时候,你就会更加迫切的想要一把锁。上锁之前,我们需要对https有一定的了解。

https如何握手

对于传统的http连接来说,其模型很简单,只需要三次握手建立TCP连接后,客户端和服务端就可以开始进行http报文的发送和响应了。而https同样是基于TCP,只是在http报文和TCP之间又加了一层握手,这个握手用于校验服务端传来的公钥的合法性(证书校验),其底层实现是基于SSL/TSL协议。

SSL协议的握手步骤是这样的:

第一步,浏览器给出协议版本号、一个浏览器客户端生成的随机数(Client random),以及客户端支持的加密方法,如RSA。

第二步,服务器收到握手请求后,确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)。

第三步,浏览器确认数字证书有效(验证过程我们在后文第二部分讲解),然后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥,加密这个随机数,发给服务器。

第四步,服务器使用自己的私钥,获取浏览器发来的随机数(即Premaster secret)。

第五步,服务器和浏览器此时应该都拥有了整个握手过程中出现的3个随机数,他们会各自根据约定的加密方法,使用前面的三个随机数,生成”对话密钥”(session key),用来加密接下来的整个对话过程。

所以一个https请求的过程中,握手阶段包含了 TCP协议的握手SSL协议的握手 的时间,总体上我通过工具测试大概SSL握手是TCP握手的三倍,而且证书的秘钥越长加解密时间则越多。 我们也能看出来,SSL协议应该属于一个应用层协议。

https会使得网站变慢?

大家最关心的就是这个协议会让我们的连接变慢,这个看起来似乎是不可避免的;毕竟建立SSL连接的过程比http多了好几次握手;然而事实就这么简单吗? 非也

作为中国人,一定对GFW毕竟熟悉了,实际上根据我多年来实际的经历来看,除了GFW,其实不管是在国内的公司还是学校(甚至运营商),实际上都有监控或劫持本组织内网络流量的嫌疑。当网站使用了https,实际上这些监控系统成为摆设,既然无法拆解你的信息,他唯一的做法自然是放过,这就大大加速了数据在网络中的传输速度。所以,使用了https表面上看起来是在连接建立阶段增加了时间,然而实际上对网站整体的速度来说,未必真的慢了。

只需要在注册登录页面使用https?

这只能防止密码劫持,并不能防止cookie劫持;这年头想劫持一个局域网络的简直易如反掌,所以如今要想安全,必须全站https

静态资源是否需要https?

如果主要页面已经https了,则你的CDN静态资源也得走https,否则浏览器会给出简单的控制台警告:

不过cdn服务器遍布全球,要想把证书安装到上面可是很费劲的。所以如果想用自己的域名来接管静态资源,要么自己部署cdn自己搞,要么把证书和秘钥交给自己的cdn服务商。但是后者实在是太危险了。所以才CDN服务商除了允许你上传自己的证书和私钥之外,也推出了申请CA证书的服务,你可以专门为CDN这个域名申请个单独的证书,这个证书是部署到CDN服务商所有服务器的(这样就不用担心自己主业务的服务器私钥泄露给第三方)。目前国内的七牛已经提供了该服务,所以我的博客图片也顺便开启了https。

https没有缓存?

是的。不过要明确这里的缓存指的是中间网络设施的缓存,而不是客户端缓存。中间网络设施无法缓存的原因在于他们根本无法获取https报文,无法读取缓存策略; 从https的意义上来看 既然想保护信息的隐私,确实也没必要让中间设施进行缓存了。

https是否足够安全?

SSL/TLS的设计只能说是从技术上最大限度地保护网络报文的安全,但它无法防止用户自己作死。

验证证书验证的步骤

一个完整的证书是CA机构颁发给网站主的,然后网站被访问时,服务器会将证书发送给浏览器。发送给浏览器的证书需要包含三部分内容:

  1. Certificate证书明文,里面包括了很多信息。比如网站域名,发证机关,有效期等;当然最重要的是网站主服务器的公钥会放在里面
  2. Certificate Signature Algorithm 证书加密算法。这是指的CA机构颁发证书时使用的非对称加密算法名称
  3. Certificate Signature Value 证书签名。这是CA机构给证书明文进行哈希得到的非对称加密结果

所以CA机构其实本质上只是负责给证书签名的,证书本身其实还是网站主自己生成的;

当SSL握手进行到证书验证这一步时,浏览器是这样验证证书的:

a)该公钥证书的subject name(主题名)和所访问的服务器站点的名称是否一致;
b)该公钥证书的是否过期;
c)该公钥证书及其签发者证书链中的证书的数字签名是否有效(层层验证,一直验证到根CA证书为止)。

我们可以看出,证书的验证过程是要跟当前访问的域名做比对的;所以不仅仅是验证证书文件本身的合法性,还包括了你访问的目标网址是否跟合法证书里的name匹配。这一点验证就可以防止后文我们所讲到的证书劫持。

其中第三步,使用的是密码学技术就是签名和签名验证。签名这个概念是用来解决认证问题的,即确保消息一定是谁谁谁发的(防冒充);对于证书来说就是确保这个证书一定是浏览器/操作系统所信任的CA机构签发的。
而签名又依赖摘要技术和非对称加密技术,即A发送一个消息给B,先把消息明文使用摘要算法加密获得一个摘要,再用私钥对摘要进行加密,加密出来的东西就叫”签名”t,然后把明文和签名t发送给B;B就可以用公钥解开签名t,再对比明文的哈希是否一致。
可以发现,如果抛开明文和明文摘要这个过程来看,证书颁发给网站,网站再传给浏览器,其实就是CA机构通过非对称加密算法来传递了一下签名,走了一遭之后浏览器再验证签名;为什么要使用非对称算法来生成签名呢? 其实我们要理解: 这里我们最想保证的是摘要的防冒充,只有摘要确保是A发送的,则经过摘要对比后,才能确保明文(证书)的真实性(确实是当初CA机构颁发的证书)。

在证书校验部分,本篇会从通俗易懂的简要概述下证书校验的步骤,而不会从概念和密码学的角度去讲解。如果需要详细了解具体加密过程,可以参考网络上09年的这篇讲解https文章: http://www.cnblogs.com/hyddd/archive/2009/01/07/1371292.html

验证证书是受信任的有何作用

证书是信任的CA机构颁发的,就能确保访问的网站是受信任的吗?
非也。证书校验只能代表这个含有公钥的证书确实是受信任的CA机构颁发的;而且证书里写的是当前访问的域名;由于浏览器认为,CA在颁发一个证书时,肯定是验证了这个公钥确实是属于当前域名所有者的;于是浏览器就亮起了“安全”的小绿灯。

然而,这中间还是会有环节出问题的。比如公钥尽管确实是信任的CA机构封装成证书的,但申请证书的人万一就是个黑客呢(黑客窃取了域名变成域名所有者)?这样黑客用自己的服务器生成了私钥、公钥,再拿公钥去CA申请了一个合法证书;接下来黑客要做的就是通过DNS劫持等手段去让用户访问到自己服务器了,当然这种证书劫持的办法其实应该算是域名入侵了。其实基本上很难实现的。

CA机构是如何验证提供公钥的人确实是当前域名所有者的

CA在颁发证书时,一方面要交钱验证当前申请者的机构(也有不交钱的),另一种办法是他会看下当前域名是否是指向你发起公钥证书申请的服务器IP(因为域名所有者肯定不会把域名指向黑客服务器);还有其他一些办法,比如让你添加到自己域名上一个txt记录来验证,确保你确实有控制这个域名,那么就给你颁发证书。

当然,对于更安全的场景,是需要提交企业营业执照的。这个说来话长,涉及到CA证书的级别和类型,如感兴趣可再深入去研究。

验证证书带来的性能开销

实际上整个证书验证的过程中,还可能因为一些原因导致耗时增加:

  1. 服务端发送的Server Certificate包可能包含上级证书链,在普遍使用2048位RSA的环境中,这个包会超过2K或者3K,在移动或慢速网络下可能会丢包并引起TCP的重传
  2. 浏览器会检查服务端证书的吊销状态—-根据服务端证书扩展项中的地址去下载黑名单或访问OCSP服务,如果这些地址无法访问或者被墙,则会让浏览器等上很长一段时间。 这可就蛋疼了,毕竟我们处在大中国,而浏览器都是舶来品
  3. 建立连接时的非对称加密算法本身非常耗时,这对CPU性能要求比较高。所以每次握手,对服务器来说都是一次压力的考验

怎么办呢? 我认为是没有办法的,为了安全我们必须做出这样的牺牲;当然这可以从http协议本身来减轻这个性能和速度开销的负担,比如http2.0就已经支持了多路复用的技术,目前的http1.1也支持keep-alive,这就大大减轻了多次创建连接带来的开销。

福利:免费https证书

请自行搜索 Let’s Encrypt

但是这个免费证书是有4个月过期时间的,每当过期时,我们需要手工去执行下cert-renew程序进行证书更新。不过我已经写好了Node.js自动更新脚本,你只需要一句命令跑起来就可以免除一切后顾之忧啦。

Refer

RSA算法原理
数字签名是什么
两种典型SSL会话劫持技术小结
SSL/TLS协议运行机制的概述
图解SSL协议
https的七个误解
SSL的延迟有多大