本文摘录自《Nodejs学习笔记》,更多章节及更新,请访问 github主页地址。欢迎加群交流,群号 197339705。

模块概览

这个模块的重要性,基本不用强调了。在网络安全问题日益严峻的今天,网站采用HTTPS是个必然的趋势。

在nodejs中,提供了 https 这个模块来完成 HTTPS 相关功能。从官方文档来看,跟 http 模块用法非常相似。

本文主要包含两部分:

  1. 通过客户端、服务端的例子,对https模块进行入门讲解。
  2. 如何访问安全证书不受信任的网站。(以 12306 为例子)

篇幅所限,本文无法对 HTTPS协议 及 相关技术体系 做过多讲解,有问题欢迎留言交流。

客户端例子

跟http模块的用法非常像,只不过请求的地址是https协议的而已,代码如下:

var https = require('https');

https.get('https://www.baidu.com', function(res){
console.log('status code: ' + res.statusCode);
console.log('headers: ' + res.headers); res.on('data', function(data){
process.stdout.write(data);
});
}).on('error', function(err){
console.error(err);
});

服务端例子

对外提供HTTPS服务,需要有HTTPS证书。如果你已经有了HTTPS证书,那么可以跳过证书生成的环节。如果没有,可以参考如下步骤

生成证书

1、创建个目录存放证书。

mkdir cert
cd cert

2、生成私钥。

openssl genrsa -out chyingp-key.pem 2048

3、生成证书签名请求(csr是 Certificate Signing Request的意思)。

openssl req -new \
-sha256
-key chyingp-key.key.pem \
-out chyingp-csr.pem \
-subj "/C=CN/ST=Guandong/L=Shenzhen/O=YH Inc/CN=www.chyingp.com"

4、生成证书。

openssl x509 \
-req -in chyingp-csr.pem \
-signkey chyingp-key.pem \
-out chyingp-cert.pem

HTTPS服务端

代码如下:

var https = require('https');
var fs = require('fs'); var options = {
key: fs.readFileSync('./cert/chyingp-key.pem'), // 私钥
cert: fs.readFileSync('./cert/chyingp-cert.pem') // 证书
}; var server = https.createServer(options, function(req, res){
res.end('这是来自HTTPS服务器的返回');
}); server.listen(3000);

由于我并没有 www.chyingp.com 这个域名,于是先配置本地host

127.0.0.1 www.chyingp.com

启动服务,并在浏览器里访问 http://www.chyingp.com:3000。注意,浏览器会提示你证书不可靠,点击 信任并继续访问 就行了。

进阶例子:访问安全证书不受信任的网站

这里以我们最喜爱的12306最为例子。当我们通过浏览器,访问12306的购票页面 https://kyfw.12306.cn/otn/regist/init 时,chrome会阻止我们访问,这是因为,12306的证书是自己颁发的,chrome无法确认他的安全性。

对这种情况,可以有如下处理方式:

  1. 停止访问:着急抢票回家过年的老乡表示无法接受。
  2. 无视安全警告,继续访问:大部分情况下,浏览器是会放行的,不过安全提示还在。
  3. 导入12306的CA根证书:浏览器乖乖就范,认为访问是安全的。(实际上还是有安全提示,因为12306用的签名算法安全级别不够)

例子:触发安全限制

同样的,通过 node https client 发起请求,也会遇到同样问题。我们做下实验,代码如下:

var https = require('https');

https.get('https://kyfw.12306.cn/otn/regist/init', function(res){
res.on('data', function(data){
process.stdout.write(data);
});
}).on('error', function(err){
console.error(err);
});

运行上面代码,得到下面的错误提示,意思是 安全证书不可靠,拒绝继续访问。

{ Error: self signed certificate in certificate chain
at Error (native)
at TLSSocket.<anonymous> (_tls_wrap.js:1055:38)
at emitNone (events.js:86:13)
at TLSSocket.emit (events.js:185:7)
at TLSSocket._finishInit (_tls_wrap.js:580:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:412:38) code: 'SELF_SIGNED_CERT_IN_CHAIN' }

ps:个人认为这里的错误提示有点误导人,12306网站的证书并不是自签名的,只是对证书签名的CA是12306自家的,不在可信列表里而已。自签名证书,跟自己CA签名的证书还是不一样的。

类似在浏览器里访问,我们可以采取如下处理:

  1. 不建议:忽略安全警告,继续访问;
  2. 建议:将12306的CA加入受信列表;

方法1:忽略安全警告,继续访问

非常简单,将 rejectUnauthorized 设置为 false 就行,再次运行代码,就可以愉快的返回页面了。

// 例子:忽略安全警告
var https = require('https');
var fs = require('fs'); var options = {
hostname: 'kyfw.12306.cn',
path: '/otn/leftTicket/init',
rejectUnauthorized: false // 忽略安全警告
}; var req = https.get(options, function(res){
res.pipe(process.stdout);
}); req.on('error', function(err){
console.error(err.code);
});

方法2:将12306的CA加入受信列表

这里包含3个步骤:

  1. 下载 12306 的CA证书
  2. 将der格式的CA证书,转成pem格式
  3. 修改node https的配置

1、下载 12306 的CA证书

在12306的官网上,提供了CA证书的下载地址,将它保存到本地,命名为 srca.cer。

2、将der格式的CA证书,转成pem格式

https初始化client时,提供了 ca 这个配置项,可以将 12306 的CA证书添加进去。当你访问 12306 的网站时,client就会用ca配置项里的 ca 证书,对当前的证书进行校验,于是就校验通过了。

需要注意的是,ca 配置项只支持 pem 格式,而从12306官网下载的是der格式的。需要转换下格式才能用。关于 pem、der的区别,可参考 这里

openssl x509 -in srca.cer -inform der -outform pem -out srca.cer.pem

3、修改node https的配置

修改后的代码如下,现在可以愉快的访问12306了。

// 例子:将12306的CA证书,加入我们的信任列表里
var https = require('https');
var fs = require('fs');
var ca = fs.readFileSync('./srca.cer.pem'); var options = {
hostname: 'kyfw.12306.cn',
path: '/otn/leftTicket/init',
ca: [ ca ]
}; var req = https.get(options, function(res){
res.pipe(process.stdout);
}); req.on('error', function(err){
console.error(err.code);
});

相关链接

Why is my node.js SSL connection failing to connect?

DER vs. CRT vs. CER vs. PEM Certificates and How To Convert Them

Painless Self Signed Certificates in node.js

利用OpenSSL创建自签名的SSL证书备忘(自建ca)

OpenSSL 与 SSL 数字证书概念贴

自签名证书和私有CA签名的证书的区别 创建自签名证书 创建私有CA 证书类型 证书扩展名

Nodejs进阶:核心模块https 之 如何优雅的访问12306的更多相关文章

  1. Nodejs进阶:核心模块net入门与实例讲解

    模块概览 net模块是同样是nodejs的核心模块.在http模块概览里提到,http.Server继承了net.Server,此外,http客户端与http服务端的通信均依赖于socket(net. ...

  2. NodeJS学习笔记 进阶 (12)Nodejs进阶:crypto模块之理论篇

    个人总结:读完这篇文章需要30分钟,这篇文章讲解了使用Node处理加密算法的基础. 摘选自网络 Nodejs进阶:crypto模块之理论篇 一. 文章概述 互联网时代,网络上的数据量每天都在以惊人的速 ...

  3. Nodejs进阶:crypto模块中你需要掌握的安全基础

    本文摘录自<Nodejs学习笔记>,更多章节及更新,请访问 github主页地址. 一. 文章概述 互联网时代,网络上的数据量每天都在以惊人的速度增长.同时,各类网络安全问题层出不穷.在信 ...

  4. Nodejs进阶:核心模块Buffer常用API使用总结

    本文摘录自<Nodejs学习笔记>,更多章节及更新,请访问 github主页地址.欢迎加群交流,群号 197339705. 模块概览 Buffer是node的核心模块,开发者可以利用它来处 ...

  5. Nodejs之express第三方核心模块的中间件——body-parser

    Node中的核心模块分两类:一类是自带的核心模块,如http.tcp等,第二类是第三方核心模块,express就是与http对应的第三方核心模块,用于处理http请求.express在3.0版本中自带 ...

  6. Nodejs核心模块

    (1)全局对象 在浏览器JS中,通常window是全局对象,而nodejs中的全局对象是global,所有全局变量都是global对象的属性. 在nodejs中能够直接访问到的对象通常都是global ...

  7. 使用NodeJS模块-NodeJS官方提供的核心模块

    除了使用自己写的本地模块以外,NodeJS可以使用另外两种类型的模块,分别是NodeJS官方提供的核心模块和第三方提供的模块 NodeJS官方提供的核心模块 NodeJS平台自带的一套基本的功能模块, ...

  8. node (02 CommonJs 和 Nodejs 中自定义模块)顺便讲讲module.exports和exports的区别 dependencies 与 devDependencies 之间的区别

    CommonJS 规范的提出,主要是为了弥补当前 JavaScript 没有标准的缺陷.它的终极目标就是:提供一个类似 Python,Ruby 和 Java 语言的标准库,而不只是停留在小脚本程序的阶 ...

  9. NodeJS学习笔记 进阶 (13)Nodejs进阶:5分钟入门非对称加密用法

    个人总结:读完这篇文章需要5分钟,这篇文章讲解了Node.js非对称加密算法的实现. 摘录自网络 地址: https://github.com/chyingp/nodejs-learning-guid ...

随机推荐

  1. mysql / mysqld_safe / mysqld 常见错误处理

    1. FATAL ERROR: Could not find ./bin/my_print_defaults [root@localhost scripts]# ./mysql_install_db ...

  2. 太阳系Demo(openGL)

    这个是8年前写的demo,提交的一份作业,按照提出的需求点,以最快和最简单的方式完成功能,因此代码比较简单. 1)截图 2) 功能点描述: 1.公转,自传 2.基础的摄像机运动 3.正视和顶视 4.天 ...

  3. 二分+最短路判定 BZOJ 2709: [Violet 1]迷宫花园

    BZOJ 2709: [Violet 1]迷宫花园 Sample Input 5 ######### # # # # # # # #S# # ##### # # ## # # # ### ### ## ...

  4. ArrayList如何实现线程安全

    一:使用synchronized关键字,这个大家应该都很熟悉了,不解释了: 二:使用Collections.synchronizedList();使用方法如下: 假如你创建的代码如下:List< ...

  5. Hash MD5 CRC 知识

    本文旨在科普安全相关的知识,并附一个C#实现的文件管理工具. Hash 安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的五种安全 ...

  6. Beanstalk消息队列的实现

    在工作中要用到消息队列,但是主管为了追求开发速度,让用了一个简易的类  beanstalk 下面来说明这个东西 参考博客:https://my.oschina.net/u/698121/blog/15 ...

  7. jvm虚拟机性能监控与故障处理工具

    java开发人员肯定知道jdk的bin目录中有java.exe javac.exe这两个命令行工具,但并非所有程序员都了解过jdk的bin目录之中其他命令行的作用.jdk的工具,体积都比较小,这些命令 ...

  8. Linux混杂设备驱动学习

    Linux混杂设备是字符设备的一类,主要是混杂设备拥有相同的主设备号(10),但是次设备号是不同的.所有的混杂设备行程一个链表,对设备访问时内核更据次设备号查找到相应的混杂设备. 混杂设备用struc ...

  9. oracle基本用法

    作为企业版的后台数据支撑,就首先要掌握oracle的使用方法!!! 注册用户之前,需要使用system管理员来进行注册功能!!! 1.首先创建新用户 2.这样就能使创建的新用户能够登陆吗?不,还需要分 ...

  10. using关键字背后的故事!

    using关键字的作用: 1:可以引入命名空间2:可以释放资源 *****不能使用using语句完全替换掉(try-catch-finally)语句(无法进行异常处理) 在出了using语句的{}后, ...