‘大家好,我是渣渣辉’。日常访问网站,随处可见的小弹窗,网页八成是被运营商劫持了。所谓运营商劫持是多指 HTTP 劫持,HTTP 协议是明文的,每次请求和响应的数据都需要经过运营商(电信、联通等),运营商便会在响应的数据中加入一些自己的东西(广告)。今年 7 月起,Chrome 浏览器会将把所有 HTTP 标示为不安全网站。故引出今天的主角 HTTPS。
HTTPS 是 HTTP 的安全形式,所有 HTTP 请求和响应的数据到达网络之前都要进行加密。
基础概念
- TLS/SSL
用于 HTTPS 的编码与解码
- 对称加密技术
加密解密使用相同的密钥相同
- 非对称加密技术
加密解密使用不同的密钥,一般使用 RSA 算法
HTTPS 原理
HTTPS 是如何保证数据安全,以客户端向服务端请求数据为例:
- 客户端向服务端请求数据,服务端将正文内容通过 HASH 算法处理,处理后的内容通过服务端密钥加密生成数字签名,向客户端发送正文内容及数字签名
- 客户端将请求到的正文内容经过相同的 HASH 算法处理,再将数字签名通过公钥解密,对照俩者的结果是否相同,如果相同则内容未被修改。
数字签名(digital signature)为非对称加密,只有一个私钥及多个公钥。但以上步骤中的公钥的来源很有可能是不安全的,为保证公钥的准确性,要去数字证书机构(简称 CA) 为公钥做认证。
数字证书也为非对称加密,将公钥及一些服务端的信息经过 CA 的私钥加密生成数字证书(证书包括签发者、证书用途、公钥、加密算法、HASH 算法、到期时间等)。客户端拿到数字证书通过 CA 的公钥解密得到数字签名的公钥,确保了公钥来源的安全性。
搭建 HTTPS
制作CA证书
- 生成CA私钥
openssl genrsa -out ca.key 1024
- 生成CA公钥
openssl req -new -x509 -days 7305 -key ca.key -out ca.crt
Common Name 要写成你要用的域名
制作证书
- 生成服务端私钥
openssl genrsa -des3 -out server.pem 1024
- 生成服务端公钥
openssl rsa -in server.pem -out server.key
- 生成签名请求
openssl req -new -key server.pem -out server.csr
- 用CA进行签名
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
测试
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('./server.key'),
cert: fs.readFileSync('./server.crt')
};
https.createServer(options, function(req, res) {
res.writeHead(200);
res.end('Holle World');
}).listen(8000);
注意事项
mac下需要先在safari下打开,信任该证书
参考
http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html https://juejin.im/post/590ec765a22b9d0058fcfaa5 http://www.barretlee.com/blog/2015/10/05/how-to-build-a-https-server/ http://blog.creke.net/762.html
comments powered by Disqus