SSL证书制作并使用NodeJs进行HTTPS认证配置

时间:2024-02-21 15:53:25

HTTP

Hyper Text Transfer Protocol

使用TCP端口默认为:80

超文本传输协议,是互联网上使用最广泛的一种协议,所有WWW文件必须遵循的标准。HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全。

HTTPS

Hyper Text Transfer Protocol over Secure Socket Layer

使用TCP端口默认为:443

安全的超文本传输协议,Netscape(网景公司)设计了 SSL(Secure Sockets Layer) 协议用于对Http协议传输的数据进行加密,保证会话过程中的安全性。SSL中文为 安全套接层

SSL简介

SSL协议位于TCP/IP协议与各种应用层协议(如HTTP)之间。SSL协议可分为两层:

  1. SSL Record Protocol (SSL记录协议)建立在可靠的传输协议(如TCP)上,为高层协议提供数据封装、压缩、加密等基本功能的支持;
  2. SSL Handshake Protocol (SSL握手协议)建立在记录协议上,用于在实际数据传输开始前,通讯双方进行身份验证、协商加密算法、交换加密秘钥等。

SSL协议即用到了 对称加密 也用到了 非对称加密(公钥加密),在建立传输链路时,SSL首先对 对称加密 的密钥使用公钥进行 非对称加密 ,链路建立好之后,SSL对传输内容使用 对称加密

  1. 对称加密 速度高,可加密内容大,用来加密会话过程中的消息。
  2. 公钥加密 加密速度慢,但能提供更好的身份认证技术,用来加密 对称加密 的秘钥。

https单向认证

Https在建立Socket连接之前,需要进行握手,具体过程如下:

客户端单向认证服务端
>>> 1. 发送客户端SSL版本等信息 >>>
<<< 2. 服务端给客户端返回SSL版本、随机数等信息,以及服务器公钥 <<<
CHECK 3. 客户端校验服务端证书是否合法,合法继续,否则警告 WAIT
>>> 4. 客户端发送自己可支持的对称加密方案给服务端供选择 >>>
WAIT 5. 服务端选择加密程度高的加密方式 CHECK
<<< 6. 将选择好的加密方案以明文方式发送给客户端 <<<
>>> 7. 客户端收到加密方式产生随机码,作为对称加密秘钥,使用服务器公钥加密后发给服务器 >>>
WAIT 8. 服务端使用私钥对加密信息进行解密,获得对称加密秘钥 CHECK
--- 9. 使用对称加密进行通信确保安全 ---

https双向认证

双向认证和单向认证原理基本差不多,只是除了客户端需要认证服务端以外,增加了服务端对客户端的认证,具体过程如下:

客户端单向认证服务端
>>> 1. 发送客户端SSL版本等信息 >>>
<<< 2. 服务端给客户端返回SSL版本、随机数等信息,以及服务器公钥 <<<
CHECK 3. 客户端校验服务端证书是否合法,合法继续,否则警告 WAIT
>>> 4. 客户端校验通过后,将自己的证书和公钥发送至客户端 >>>
WAIT 5. 对客户端校验,校验结束后获得客户端公钥 CHECK
>>> 6. 客户端发送自己可支持的对称加密方案给服务端供选择 >>>
WAIT 7. 服务端选择加密程度高的加密方式 CHECK
<<< 8. 将选择好的加密方案以客户端公钥进行加密后方式发送给客户端 <<<
>>> 9. 客户端收到加密方式,使用私钥进行解密,产生随机码,作为对称加密秘钥,使用服务器公钥加密后发给服务器 >>>
WAIT 10. 服务端使用私钥对加密信息进行解密,获得对称加密秘钥 CHECK
--- 11. 使用对称加密进行通信确保安全 ---

使用openssl进行证书生成

由于TLS(SSL)是基于非对称的加密体系,所以在开发前需要准备用于加密解密及验证的私钥及数字证书。这里分别为CA、服务器、客户端分别准备1套密钥及证书。

生成CA证书及秘钥

  1. 生成一个秘钥为ca-key.pem
openssl genrsa -out ca-key.pem -des 1024

 

  1. 根据秘钥ca-key.pem生成一个证书签名请求文件ca-csr.pem,根据这个文件可以签出秘钥对应的证书。在这里会要求填入相关信息,可以用“.”表示为空,但Common Name必须要填入对应域名,否则浏览器检查证书与签名域名不相符会不允许通过。
openssl req -new -key ca-key.pem -out ca-csr.pem

 

  • 另可以不执行第一步,直接执行以下语句,也会自动生成一个private.pem以及ca-csr.pem。
openssl req -new -out ca-csr.pem

 

  1. 利用证书签名请求文件ca-csr.pem,并利用ca-key.pem签名生成证书ca-cert.pem。其中x509为证书格式X.509,-days为有效期天数。
openssl x509 -req -days 3650 -in ca-csr.pem -signkey ca-key.pem -out ca-cert.pem

 

  • 当然,也可以拿着ca-csr.pem去权威的第三方申请一个证书,这样的话申请得到的证书是被接收的。现在我们自签自申证书,则如上所示使用证书签名请求文件签一个证书。

生成服务端证书及秘钥

  1. 生成一个服务器私钥为server-key.pem
openssl genrsa -out server-key.pem 1024

 

  1. 生成证书签名请求文件server-csr.pem
openssl req -new -key server-key.pem -out server-csr.pem

 

  • 另,假如我们需要多DNS和多IP的主机使用同一个证书完成验证,则不能通过上面的命令来实现。我们需要一个openssl.cnf配置文件,并执行以下语句
openssl req -new -key server-key.pem -config openssl.cnf -out server-csr.pem

 

  • openssl.cnf配置文件内容格式如下所示:
[req]  
    distinguished_name = req_distinguished_name  
    req_extensions = v3_req  
  
    [req_distinguished_name]  
    countryName = Country Name (2 letter code)  
    countryName_default = CN  
    stateOrProvinceName = State or Province Name (full name)  
    stateOrProvinceName_default = BeiJing  
    localityName = Locality Name (eg, city)  
    localityName_default = YaYunCun  
    organizationalUnitName  = Organizational Unit Name (eg, section)  
    organizationalUnitName_default  = Domain Control Validated  
    commonName = Internet Widgits Ltd  
    commonName_max  = 64  
  
    [ v3_req ]  
    # Extensions to add to a certificate request  
    basicConstraints = CA:FALSE  
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment  
    subjectAltName = @alt_names  
  
    [alt_names]  
    DNS.1 = ns1.dns.com  
    DNS.2 = ns2.dns.com  
    DNS.3 = ns3.dns.com  
    IP.1 = 192.168.1.84  
    IP.2 = 127.0.0.1  
    IP.3 = 127.0.0.2  

 

  1. 生成服务器证书为server-sert.pem,具体选项含义查询openssl
openssl x509 -req -days 730 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in server-csr.pem -out server-cert.pem -extensions v3_req -extfile openssl.cnf

 

生成客户端证书及秘钥

  1. 生成客户端秘钥client-key.pem
openssl genrsa -out client-key.pem 

 

  1. 生成证书签名请求文件client-csr.pem
openssl req -new -key client-key.pem -out client-csr.pem

 

  1. 生成服务器证书为server-sert.pem,具体选项含义查询openssl
openssl x509 -req -days 365 -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in client-csr.pem -out client-cert.pem

 

打包和转换

  1. 另外的,我们可以将服务器的私钥、证书、CAz证书打包成一个单独的.pfx或.p12文件以便于使用,比如.p12导入浏览器可以让浏览器信任该证书
openssl pkcs12 -export -in server-cert.pem -inkey server-key.pem -certfile ca-cert.pem -out server.pfx 
openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -certfile ca-cert.pem -out client.p12 

 

  1. 证书的转换,由10打包好的文件,可以经过转换变为其他格式以下提供常见的格式转换方法
openssl pkcs12 -export -inkey test.key -in test.cer -out test.pfx
openssl pkcs12 -in test.pfx -nodes -out test.pem 
openssl rsa -in test.pem -out test.key
openssl x509 -in test.pem -out test.crt

 

单向验证和双向验证的配置

node.js 实现HTTPS的配置

  1. 导入https, fs
var https = require (\'https\');  // https服务器
const fs = require("fs");       // 文件输入输出,用来导入证书

 

  1. 导入证书,利用fs导出三个证书并存入变量
var privateKey = fs.readFileSync(\'./cert/ca.key\').toString();
var certificate = fs.readFileSync(\'./cert/ca.crt\').toString();
var client_certificate = fs.readFileSync(\'./cert/client.crt\').toString();

 

  1. https设置,利用键值对来进行设置,rrequestCert表示是否需要客户端证书,rejectUnauthorized表示如果客户端证书不符合则是否拒绝访问,这两个为true则意味着双向认证,否则为单向认证
var credentials = { key: privateKey, 
                    cert: certificate, 
                    ca: client_certificate, 
                    requestCert: true, 
                    rejectUnauthorized: true};

 

  1. 创建服务器对象,比http多了一个参数,即3中所提的credentials
var server = http.createServer(app);                // 若http只需要一个参数就行
var server = https.createServer(credentials, app);  // https需要参数

 

  1. 开启端口监听
server.listen(port);    // port即为端口号
 

喜欢这篇文章?欢迎打赏~~