• Node学习十五 —— 使用TLS/SSL提高安全性


    使用TLS/SSL保证服务器的安全性

    传输层安全(Transport Layer Security,TLS)和 安全套接字层(Secure Socket Layer,SSL)允许客户端/服务器应用程序以组织窃听和篡改的方式通过网络进行通信。他们会在传输层上对网络连接进行加密,这使得隐私和消息都能得到验证。

    TLS是基于Netscape公司开发的早期SSL规范,实际上,TLS 1.0 也被成为 SSL 3.1。

    一、理解私钥和公钥

    公钥加密指需要两个独立的加密系统,一个秘钥用来加密明文,另一个用来解密已经加密的消息。其中一个秘钥是共有的,另一个是私有的。如果明文使用公钥进行加密,那么只能用私钥进行解密,这可以让公钥和私钥的拥有者进行私有通信。如果明文使用私钥加密的,公钥就可以对其进行解密,并且系统会验证私钥拥有者在文档上的签名。

    公钥证书使用数字签名绑定公钥和身份信息、文档会由认证中心进行签名,完成验证匹配公钥的身份信息的过程。认证中心会响应其他证书,无论这个证书是自签名还是有其他认证中心签名的,这样就会形成一个授权链,这个授权链是公钥基础结构的一部分。

    每台计算机都会定义一组根认证中心,在默认情况下用它们来验证认证和认链。在使用Node的TLS库时,可以使用这些默认的认证中心或者自定义的认证中心。

    1.1 产生私钥

    注意:

    Node中的TLS是基于OpenSSL库实现的,可能你已经安装了,也可能没有,所以需要自己检查一下

    TLS依赖于公钥/私钥基础结构,在这个基础结构中,每个客户端和服务器都必须有一个私钥对消息签名。

    openssl程序可以在命令行上创建私钥:

    $ openssl genrsa -out my_key.pem 1024
    

    1.2 产生公钥

    设计TLS的服务器和客户端在彼此验证的时候必须具有一个证书,是由认证中心签名或者自签名的公钥。获取证书的第一步是创建一个证书签发请求:

    $ openssl req -new -key my_key.pem -out my_csr.pem
    

    自签名:

    $ openssl x509 -req -in my_csr.pem -signkey my_key.pem -out my_cert.pem
    

    二、构建TLS服务器

    TLS服务器是net.Server的子集,能用net.Server创建什么就能用TLS创建什么。但是使用TLS服务器的时候,使用的是安全连接。

    2.1 初始化服务器

    初始化TLS服务器要复杂一些,因为还需要传入服务器的私钥和证书文件:

    const tls = require('tls');
    const fs = require('fs');
    
    const options = {
        key: fs.readFileSync('./key.pem'),
        cert: fs.readFileSync('./my_certificate.pem')
    }
    
    const server = tls.createServer(serverOptions);
    

    2.2 监听连接

    server.listen(port);
    

    当有连接到达,会发射secureConnection事件,并将其传入套接字来注册回调函数。

    server.on('secureConnection',(stream)=>{})
    

    2.3 从客户端读取数据

    当有连接到达,回调函数可以拿到一个tls.CleartextStream实例,该对象是一个双向流,只需要绑定data事件就可获取客户端数据。

    server.on('secureConnection', (clientStream) => {
        clientStream.on('data', (data)=>{
            ...
        })
    })
    

    2.4 向客户端发送数据

    clientStream.write('hello');
    

    2.5 终止连接

    clientStream.end("Bye!");
    

    三、构建TLS客户端

    要创建到服务器的连接,首先需要发布秘钥和证书,没有则需要创建。

    3.1 初始化客户端

    必须用几个选项来初始化客户端连接。首先需要获得这些选项,如果事先已经创建了私钥和数字证书,可以用fs读取他们:

    const options = {
    	key: fs.readFileSync('...'),
        cert: fs.readFileSync('...'),
    }
    

    3.2 连接服务器

    使用tls.connect连接服务器:

    const client = tls.connect(port, host, options, () => {
        ...
    })
    

    3.3 验证服务器证书

    是要和公钥允许你创建一个条安全信道,然而,在创建之后,你还想确认一下是否正确连接目标服务器,可以查看服务器证书。

    为了能够查看服务器证书,需要学习一些未曾见过的TLS连接选项,其中之一就c,它是授权中心的缩写。如果忽略该选项,会使用默认的一组根证书。默认证书集会自用被客户端用来校验服务器信息。

    如果成功,CleartextStream会将属性authorized设置为true。

    3.4 向服务器发送数据

    client.write('Hello!');
    

    3.4 读取数据

    一旦连接服务器,就可以监听data事件并接收数据:

    client.on('data', (data)=>{
        console.log(data);
    })
    

    3.5 终止连接

    client.end('bye');
    
  • 相关阅读:
    产品经理需要懂技术吗?
    最新消息!2022年全国大学生数学建模竞赛评阅要点发布
    语句覆盖就是设计测试用例,运行测试程序,使得每一可执行语句至少执行一次。 判定覆盖:设计测试用例,使程序中的每个逻辑判定的取真和取假的分支至少经历一次。条件覆盖基本思想:设计用例,使每个判断中的每个
    微信小程序入门讲解【超详细】
    C++数据结构--红黑树
    Es6 箭头函数
    信息检索 | 常见专类信息检索系统一览
    Python:整数四则运算及格式化输出
    【JavaSE】JavaSE之控制逻辑
    输入的这些数是否对称
  • 原文地址:https://blog.csdn.net/qq_51574759/article/details/127044148