数据传输安全
151
购买证书后
CA
会验证并处理
CSR
,然后签发证书,供你安装(一般通过
电子邮件发给你)。很多
CA
还提供通配证书,让你保护根域名下的所有子
域名。
创建供测试的自签名证书
在生产环境使用会导致错误
稍后你将看到,如果你的网站真的有人访问,一定不能在生产环境使用自签
名证书。自签名证书的唯一目的是测试。浏览器遇到自签名证书时会显示一
个警告信息,告诉访客你的证书不可信。我已经提醒你了!警告消息如图
7-5
所示,这个消息会占据整个浏览器窗口,不让你查看网站内容。
7
-
5
:不受信证书警告
我已经提醒你了,本节的内容只适用于测试。下面说明如何自己签发供测试
的证书。这样便可以在部署到生产环境之前单独搭建一个环境,用于测试。
前几节讲过如何设置供生产环境使用的证书,接下来将说明设置自签名证书
的步骤。
设置证书
首先要创建一个私钥和自签名证书,提供给
Node
服务器使用。
152
7
为了举例方便,我们将把私钥与程序存储在同一个文件夹中。打开一个终端
窗口,进入程序所在的文件夹。
先来生成私钥。执行下述命令:
openssl genrsa -des3 -out server.key 2048
这个命令会要求你输入并确认一个密码。这个命令会创建一个
2048
位、
DES
三重加密的
RSA
密钥,然后使用密码加密,最后存储在
server.enc.key
文件中。
这个过程如图
7-6
所示。
7
-
6
:生成一个
2048
RSA 密钥
接下来要创建一个证书签名请求
CSR
使用前面生成的密钥,执行下述命令
openssl req -new -key server.key -out server.csr
这个命令会创建证书签名请求,把输出的
CSR
保存到
server.csr
文件中。这
个命令会要求你输入关于自己和公司的更多详细信息:
私钥的密码(与前一个命令使用的一样)。
两位国家代码。
州或省。
城市或地区名。
公司或组织名。
在公司中的部门。
数据传输安全
153
供证书请求使用的名称或你自己的名字。
能联系到你的电子邮件地址。
此外,这个命令还会要求你提供额外的信息,包括:
质询密码。
公司名称(可选)。
从头到尾的整个过程如图
7-7
所示。
7
-
7
:创建证书签名请求
去掉密钥的密码
使用自签名证书测试时,如果想去掉私钥的密码(除了在本地供自己测试之
外,不建议这么做),可以使用前面生成的加密私钥(假如是 server.enc.
key)生成一个没有加密的私钥(server.key),要执行的命令如下:
openssl rsa -in server.enc.key -out server.key
参照本节所述的步骤,接下来应该执行的命令如下:
openssl genrsa -des3 -out server.enc.key 2048
openssl req -new -key server.enc.key -out server.csr
openssl rsa -in server.enc.key -out server.key
154
7
得到
CSR
之后,我们便可以自己签名证书,创建所需的证书文件
CRT
)。
请执行下述命令:
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
这个命令创建一个有效期一年(通过 -days选项指定)的临时证书。如果没
有去掉私钥的加密,这一步会要求你输入密码,如图
7-8
所示。
7
-
8
:创建自签名证书
现在,这个自签名证书可在服务器中使用了。设置好服务器之后,服务器和
浏览器之间就将建立起
HTTPS
连接。
设置服务器
下述服务器示例的完整代码在
https://github.com/iddatasecuritybook/chapter7/
blob/master/self-signed-cert/server.js
为了举例方便,我们假定你在上一节没有去掉私钥的加密。但是,我们仍
将说明去掉密码后如何修改代码。我们的示例代码还假定你已经安装好了
Express
我们将让一个
Express
服务器使用前面创建的私钥和自签名证书提供
HTTPS
通过安全连接与另一个源(例如浏览器或本地运行的其他程序)通信。
这里,另一个程序将通过安全的链接把
JSON
字符串发给服务器。
这个服务器将使用几个模块,其中 fshttps querystring 在标准库中,
无需通过
npm
安装;此外,还将使用 body-parser 处理
JSON/URL
编码的主
体(
Express 4.0
及以上版本需要)body-parser 通过下述命令从
npm
中安装
数据传输安全
155
npm install body-parser --save
先看服务器的完整代码,然后再说明每一步:
var fs = require('fs'),
https = require('https'),
querystring = require('querystring'),
bodyParser = require('body-parser')
app = require('express')();
//
支持
JSON
URL
编码的主体
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
//
处理所有
POST
请求
app.post('/', function (req, res){
var message = req.body;
res.send('Message received:' + querystring.stringify(message));
});
//
设置证书选项
var options = {
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.crt'),
passphrase: 'YOUR KEY PASSWORD'
};
//
使用证书选项创建服务器
https.createServer(options, app).listen(3000, function () {
console.log('Server started: Listening on port 3000');
});
在上述示例代码中,密码需要你输入。这样的值决不能直接写在代码中,而
应该使用环境变量、有访问权限限制的文件等存储。
Node
模块 dotenv 是不
错的选择。这个模块的使用方法参见附录
B
的“应用配置”。
前两段代码先引入所需的模块,然后设置 body-parser 的选项,让
Express
JSON
URL
编码的字符串。
然后,处理发给服务器的所有入站
POST
请求。为此,我们定义了 app.
post(/,
...
) 路由。在回调函数中,先提 req.body这是浏览器或其他程序
发送的
POST
对象。这里,我们只是简单地回送一个文本,表示消息已收到。

Get Web开发的身份和数据安全 now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.