HTTPS 的原理和 NodeJS 的实现

基本原理

HTTP协议采用明文传输数据,当涉及敏感信息的传送时,极有可能会受到窃听或者中间人的攻击。HTTPS是HTTP与SSL/TLS的组合,即便用加密通信以及网络服务器的身份鉴定来进行信息的安全传输。其核心有二:算法

  • 使用证书对服务器及请求端的身份验证
  • 使用一组对称秘钥加密包括请求头在内的全部信息传输

握手流程

HTTPS连接的创建过程当中涉及到服务器端证书、客户端证书(可选)、服务器端的非对称秘钥以及后续通讯过程当中使用的对称秘钥几个内容。安全

  1. 客户端对HTTPS的地址发出请求,而且将本身的SSL版本号等信息发送给服务器
  2. 服务器接收到请求,将服务器证书和公钥等信息返回给客户端
  3. 客户端接收到证书后向证书颁发机构验证证书的合法性。若是证书不合法(好比自行签发的证书),则向用户发出警告并确认是否继续,用户能够选择在此时离开终止HTTPS的连接。
  4. 证书合法或客户端确认在不安全的状况下继续,客户端生成pre-master secret而且使用2中收到的服务器公钥加密后发送给服务器。若是是使用交互策略的TLS,则同时须要将客户端的证书发送给服务器。服务器检查客户端的证书颁发机构是否在信任列表中,以及证书内容是否合法。若不合法,结束本次会话。
  5. 服务器使用私钥解密pre-master secret,而后双方经过一种实现商定好的加密算法生成本次通信使用的master secret
  6. 双方互相通知对方本次SSL握手成功,其后均使用master secret对传输内容进行加密。

下图简要的说明了这个流程的实现。
图片描述服务器

一开始我也心存疑问:为何要单独使用另一组对称秘钥来实现对信息的加密而不直接使用服务器和客户端双方的非对称秘钥呢?我自身很是认同下面这个回答的解释:网络

传输过程使用对称密钥是由于对称加密比非对称加密的运算量低一个数量级以上,因此这样的方式能够提升双方会话的运算速度。ui

对于加密算法不是很是了解,但愿大牛指点一二。加密

Openssl自签名证书的生成

HTTPS中一个关键就是证书文件。固然咱们能够找专业的第三方机构签发。本身玩玩的话就用自签名的证书就能够了,用户在访问的时候则须要确认安全性问题。
一、生成传输pre-master secret的时候所须要的Server端的私钥,运行时提示须要输入密码,用于对key的加密。之后每次读取此文件的时候,都须要输入指令。spa

# 生成服务器端的非对称秘钥
openssl genrsa -des3 -out server.key 1024

# 生成签名请求的CSR文件
openssl req -new -key server.key -out server.csr

# 本身对证书进行签名,签名的有效期是365天
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

# 去除证书文件的password
cp server.key server.key.orig
openssl rsa -in server.key.orig -out server.key

最终在创建HTTPS连接中使用的文件是code

  • server.crt
  • server.key

NodeJS创建一个HTTPS的Server

var httpsModule = require('https');
var fs = require('fs');

var https = httpsModule.Server({
     key: fs.readFileSync('/path/to/server.key'),
     cert: fs.readFileSync('/path/to/server.crt')
}, function(req, res){
    res.writeHead(200);
    res.end("hello world\n");
});

//https默认de监听端口时443,启动1000如下的端口时须要sudo权限
https.listen(443, function(err){  
     console.log("https listening on port: 443");
});

这里使用的fs.readFileSync方法会阻塞其余进程直到文件的读取完毕,在读取关键的配置文件的时候这样的方法是比较适宜的。server

相关文章
相关标签/搜索