HTTPS证书生成原理和部署细节
看看下面,部分电信用户访问京东首页的时候,会看到右下角有一个浮动广告:
小白用户以为是京东有意放置的,细心的用户会发现,这个 iframe 一层嵌一层的恶心广告很明显是电信/中间人通过 DNS 劫持注入进去的,十分恶心,没有关闭按钮。
随着互联网的快速发展,我们几乎离不开网络了,聊天、预订酒店、购物等等,我们的隐私无时无刻不暴露在这庞大的网络之中,HTTPS 能够让信息在网络中的传递更加安全,增加了 haker 的攻击成本。
HTTPS 区别于 HTTP,它多了加密(encryption),认证(verification),鉴定(identification)。它的安全源自非对称加密以及第三方的 CA 认证。
简述 HTTPS 的运作
如上图所示,简述如下:
客户端生成一个随机数
random-client
,传到服务器端(Say Hello)服务器端生成一个随机数
random-server
,和着公钥,一起回馈给客户端(I got it)客户端收到的东西原封不动,加上
premaster secret
(通过random-client
、random-server
经过一定算法生成的东西),再一次送给服务器端,这次传过去的东西会使用公钥加密服务器端先使用私钥解密,拿到
premaster secret
,此时客户端和服务器端都拥有了三个要素:random-client
、random-server
和premaster secret
此时安全通道已经建立,以后的交流都会校检上面的三个要素通过算法算出的
session key
CA 数字证书认证中心
如果网站只靠上图运作,可能会被中间人攻击,试想一下,在客户端和服务端中间有一个中间人,两者之间的传输对中间人来说是透明的,那么中间人完全可以获取两端之间的任何数据,然后将数据原封不动的转发给两端,由于中间人也拿到了三要素和公钥,它照样可以解密传输内容,并且还可以篡改内容。
为了确保我们的数据安全,我们还需要一个 CA 数字证书。HTTPS的传输采用的是非对称加密,一组非对称加密密钥包含公钥和私钥,通过公钥加密的内容只有私钥能够解密。上面我们看到,整个传输过程,服务器端是没有透露私钥的。而 CA 数字认证涉及到私钥,整个过程比较复杂,我也没有很深入的了解,后续有详细了解之后再补充下。
CA 认证分为三类:DV ( domain validation),OV ( organization validation),EV ( extended validation),证书申请难度从前往后递增,貌似 EV 这种不仅仅是有钱就可以申请的。
对于一般的小型网站尤其是博客,可以使用自签名证书来构建安全网络,所谓自签名证书,就是自己扮演 CA 机构,自己给自己的服务器颁发证书。
生成密钥、证书
第一步,为服务器端和客户端准备公钥、私钥
# 生成服务器端私钥 |
第二步,生成 CA 证书
# 生成 CA 私钥 |
在执行第二步时会出现:
➜ keys openssl req -new -key ca.key -out ca.csr |
注意,这里的 Organization Name (eg, company) [Internet Widgits Pty Ltd]:
后面生成客户端和服务器端证书的时候也需要填写,不要写成一样的!!!可以随意写如:My CA, My Server, My Client。
然后 Common Name (e.g. server FQDN or YOUR name) []:
这一项,是最后可以访问的域名,我这里为了方便测试,写成 localhost
,如果是为了给我的网站生成证书,需要写成 barretlee.com
。
第三步,生成服务器端证书和客户端证书
# 服务器端需要向 CA 机构申请签名证书,在申请签名证书之前依然是创建自己的 CSR 文件 |
此时,我们的 keys 文件夹下已经有如下内容了:
. |
看到上面两个 js 文件了么,我们来跑几个demo。
HTTPS本地测试
服务器代码:
// file http-server.js |
短短几行代码就构建了一个简单的 https 服务器,options 将私钥和证书带上。然后利用 curl 测试:
➜ https curl https://localhost:8000 |
当我们直接访问时,curl https://localhost:8000
一堆提示,原因是没有经过 CA 认证,添加 -k
参数能够解决这个问题:
➜ https curl -k https://localhost:8000 |
这样的方式是不安全的,存在我们上面提到的中间人攻击问题。可以搞一个客户端带上 CA 证书试试:
// file http-client.js |
先打开服务器 node http-server.js
,然后执行
➜ https node https-client.js |
如果你的代码没有输出 hello world
,说明证书生成的时候存在问题。也可以通过浏览器访问:
提示错误:
此服务器无法证明它是localhost;您计算机的操作系统不信任其安全证书。出现此问题的原因可能是配置有误或您的连接被拦截了。
原因是浏览器没有 CA 证书,只有 CA 证书,服务器才能够确定,这个用户就是真实的来自 localhost 的访问请求(比如不是代理过来的)。
你可以点击 继续前往localhost(不安全)
这个链接,相当于执行 curl -k https://localhost:8000
。如果我们的证书不是自己颁发,而是去靠谱的机构去申请的,那就不会出现这样的问题,因为靠谱机构的证书会放到浏览器中,浏览器会帮我们做很多事情。初次尝试的同学可以去 startssl.com 申请一个免费的证书。
Nginx 部署
ssh 到你的服务器,对 Nginx 做如下配置:
server_names barretlee.com *.barretlee.com |
会发现,网页 URL 地址框左边已经多出了一个小绿锁。当然,部署好了之后可以去这个网站看看测评分数,如果分数是 A+,说明你的 HTTPS 的各项配置都还不错,速度也很快。
小结
好吧,我也是初次尝试,本地测试是 ok 的,由于买的阿里云服务器到期了也没续费,就没远程折腾,其实本地 Nginx + Nodejs,然后 Hosts 配置域名也是可以较好模拟的。文中很多地方描述的可能不是十分准确,提到的点也不够全面,如果有错误,还请斧正!
建议继续学习:
- HTTPS, SPDY和 HTTP/2性能的简单对比 (阅读:15913)
- HTTPS的七个误解 (阅读:4396)
- iOS安全系列之二:HTTPS进阶 (阅读:2658)
- 外链点击没有 referrer 信息?! (阅读:2271)
- iOS安全系列之一:HTTPS (阅读:1939)
- SSLStrip 的未来 —— HTTPS 前端劫持 (阅读:1859)
- 在 Django/Flask 开发服务器上使用 HTTPS (阅读:1782)
- 你所不知道的 HSTS (阅读:1832)
- Linux使用curl访问https站点时报错汇总 (阅读:1618)
- 三种解密 HTTPS 流量的方法介绍 (阅读:1464)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:小胡子哥的个人网站 来源: 小胡子哥的个人网站
- 标签: HTTPS
- 发布时间:2016-02-29 23:47:16
- [55] IOS安全–浅谈关于IOS加固的几种方法
- [54] 图书馆的世界纪录
- [54] android 开发入门
- [54] 如何拿下简短的域名
- [52] Oracle MTS模式下 进程地址与会话信
- [52] Go Reflect 性能
- [49] 【社会化设计】自我(self)部分――欢迎区
- [48] 读书笔记-壹百度:百度十年千倍的29条法则
- [41] 程序员技术练级攻略
- [35] 视觉调整-设计师 vs. 逻辑