使用Node 搭建HTTPS服务

来源:互联网 发布:excel保存数据丢失 编辑:程序博客网 时间:2024/06/05 15:44

 HTTPS 理论

 1.对HTTPS 原理

 

前面已经讲过,不在赘述: HTTPS原文链接http://blog.csdn.net/yuanmengong886/article/details/54618351

2. 数字证书

   是一种用于电脑的身份识别机制。由数字证书颁发机构(CA)对使用私钥创建的签名请求文件做的签名(盖章),表示CA结构对证书持有者的认可。

 证书优点:

   1 使用数字证书能够提高用户的可信度

   2 数字证书中的公钥,能够与服务端的私钥配对使用,实现数据传输过程中的加密和解密

   3 在证认使用者身份期间,使用者的敏感个人数据并不会被传输至证书持有者的网络系统上   

 X.509 证书

   X.509证书包含三个文件:key,csr,crt。

  key是服务器上的私钥文件,用于对发送给客户端数据的加密,以及对从客户端接收到数据的解密

  csr是证书签名请求文件,用于提交给证书颁发机构(CA)对证书签名

  crt是由证书颁发机构(CA)签名后的证书,或者是开发者自签名的证书,包含证书持有人的信息,持有人的公钥,以及签署者的签名等信息

备注:在密码学中,X.509是一个标准,规范了公开秘钥认证、证书吊销列表、授权凭证、凭证路径验证算法等。

 3.CA证书验证流程:

 

  

 

 HTTPS 实践

 单项认证

   第一步:为服务器端准备公钥、私钥

# 生成服务器端私钥

openssl genrsa -out server.key 1024

# 生成服务器端公钥

openssl rsa -in server.key -pubout -out server.pem

 第二步:生成 CSR(证书请求文件)

   # 生成 CSR(Certificate Secure Request)

   openssl req -new -key server.key -out server.csr

   生成内容如下

➜  keys  openssl req -new -key ca.key -out ca.csr

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country Name (2 letter code) [AU]:CN

State or Province Name (full name) [Some-State]:Zhejiang

Locality Name (eg, city) []:Hangzhou

Organization Name (eg, company) [Internet Widgits Pty Ltd]:My CA

Organizational Unit Name (eg, section) []:

Common Name (e.g. server FQDN or YOUR name) []:localhost

Email Address []:

   注意:

        1.上面的Common name可以是域名(IP),或者名字

        当是生成服务器端的证书请求文件: commmon name要和自己的网站域名一致

        当是生成客户端的证书请求文件时,写成自己的名字或者域名都行

        2.这里的 Organization Name (eg, company) [Internet Widgits Pty Ltd]: 后面生成客户端和服务器端证书的时候也需要填写,不要写成一样的!!!可以随意写如:My CA, My Server, My Client

    

  第三步:生成CA证书

   1).使用自己的私钥作为CA进行自签名

# server.key  作为CA的私钥进行CA签名

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

 2).使用不受操作系统提高的CA机构信任的CA机构进行CA签名

   1. 生成CA证书

   # 生成 CA 私钥

  openssl genrsa -out ca.key 1024

  # X.509 Certificate Signing Request (CSR) Management.

  openssl req -new -key ca.key -out ca.csr

  # X.509 Certificate Data Management.       CA机构向上一级CA机构签名提供证书请求文件.csr和 上一级机构的私钥 .key文件生成 签名证书.crt

  openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt

   2. CA机构  使用自己的 上级机构生成的证书 ca.crt和 自己的私钥 ca.key对证书请求文件进行签名

  # 向自己的 CA 机构申请证书,签名过程需要 CA 的证书和私钥参与,最终颁发一个带有 CA 签名的证书

  openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt


 此时,我们的keys文件夹目录如下

├── https-server.js

└── keys

    ├── ca.crt         

    ├── ca.csr

    ├── ca.key

    ├── ca.pem

    ├── ca.srl

    ├── server.crt

    ├── server.csr

    ├── server.key

    └── server.pem

   3). 将证书签名文件 server.csr 交给CA机构进行CA签名,步奏和上面第二种方案一样,唯一区别是ca.crt和ca.key是正式的CA机构的

   

   

HTTPS单项认证服务器端测试代码:

// file http-server.js

var https = require('https');

var fs = require('fs');

var options = {

  key: fs.readFileSync('./keys/server.key'),

  cert: fs.readFileSync('./keys/server.crt')

};

https.createServer(options, function(req, res) {

  res.writeHead(200);

  res.end('hello world');

}).listen(8000);

HTTPS单线认证缺点:

   容易遭受第三方( 中间人)攻击例如:

   1. 使用代理作为中间人进行抓包截取数据

   2. curl -k  https://localhost:8000  可以获取服务器的数据

双向认证

 单项认证只有客户端对服务器端的认证,没有服务器端对客户端的认证

 双向认证不仅需要服务器对客户端身份的认证,也需要客户端对服务器端身份的认证

   第一步:为服务器端和客户端准备公钥、私钥

# 生成服务器端私钥

openssl genrsa -out server.key 1024

# 生成服务器端公钥

openssl rsa -in server.key -pubout -out server.pem

# 生成客户端私钥

openssl genrsa -out client.key 1024

# 生成客户端公钥

openssl rsa -in client.key -pubout -out client.pem

   第二步:生成 CSR(证书请求文件)

   # 服务器生成 CSR(Certificate Secure Request)

   openssl req -new -key server.key -out server.csr

   # client 端

   openssl req -new -key client.key -out client.csr

  第三步:生成CA证书

 利于前面已生成的CA 机构的 私钥和签名证书对  服务端和客户端的 证书请求文件进行签名

# 向自己的 CA 机构申请证书,签名过程需要 CA 的证书和私钥参与,最终颁发一个带有 CA 签名的证书

openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt

# client 端到 CA 签名

openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt

此时,我们的 keys 文件夹下已经有如下内容了     

├── https-client.js

├── https-server.js

└── keys

    ├── ca.crt

    ├── ca.csr

    ├── ca.key

    ├── ca.pem

    ├── ca.srl

    ├── client.crt

    ├── client.csr

    ├── client.key

    ├── client.pem

    ├── server.crt

    ├── server.csr

    ├── server.key

    └── server.pem

 

 HTTPS双项认证服务器端测试代码和单项认证一样,客户端代码如下:

// file http-client.js

var https = require('https');

var fs = require('fs');

var options = {

  hostname: "localhost",

  port: 8000,

  path: '/',

  methed: 'GET',

  key: fs.readFileSync('./keys/client.key'),

  cert: fs.readFileSync('./keys/client.crt'),

  ca: [fs.readFileSync('./keys/ca.crt')]

};

options.agent = new https.Agent(options);

var req = https.request(options, function(res) {

  res.setEncoding('utf-8');

  res.on('data', function(d) {

    console.log(d);

  });

});

req.end();

req.on('error', function(e) {

  console.log(e);

});

 

  先打开服务器 node http-server.js,然后执行

  node https-client.js

  hello world

   遇见的问题保存: 'DEPTH_ZERO_SELF_SIGNED_CERT'

   由于HTTPS服务器会对客户端的证书进行验证,而客户端的证书是自签的证书,不是CA机构办法的,固然操作系统的根证书验证通不过

   需要将rejectUnauthorized:false 告诉服务器不要进行根证书列表的验证

   同时将ca: [fs.readFileSync('./keys/ca.crt')],  以保证数据双向传输的安全

原创粉丝点击