一、简介

在前后端通信过程中,一些敏感信息,特别是用户的账号密码,需要加密进行传输,如何选择加密方式也是一门学问,这里倒也不过多偏题了。 通常来说B/S架构中用的比较多的传输数据加密是RSA加密,核心思想就是公钥加密,私钥解密。 公钥,可以理解为可以公开的钥匙,服务器将公钥发给客户端,客户端用公钥对数据进行加密传输,服务器收到客户端传来的密文,再用自己的配对的私钥进行解密,即可获得原始的数据。

大致流程如下图所示: 

二、示例

2.1 生成公私钥对

Node中有一个核心模块——crypto提供各种加密、解密相关API。以下示例是基于Node@12.15.0版本进行编写。

const crypto = require('crypto');

/**
 * 生成RSA公私钥对
 * @return {*} publicKey: 公钥;privateKey: 私钥
 */
function genRSAKeyPaire() {
  const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 4096,
    publicKeyEncoding: {
      type: 'pkcs1',
      format: 'pem',
    },
    privateKeyEncoding: {
      type: 'pkcs1',
      format: 'pem',
    },
  });
  return { publicKey, privateKey };
}

// 打印生成的公私钥对
console.log(genRSAKeyPaire());

输出示例如下:

(示例公私钥已被删除了一部分,请勿用于实验)

{
  publicKey: '-----BEGIN RSA PUBLIC KEY-----\n'
    'MIICCgKCAgEAsitohTu9Jf2h NPV4tNfFhPrlbStzXNM8wSEcskwtpwi6aZfgQC7\n'
    '/A7M1hN8Zk8WgiZjy05AHinWPvXo70OWj8TminIAjB2wh0nDqm IQqN7r20uzeJm\n'
    'GBf1KusGemChEiFwiad1h/OB9z9LC8zMYR/G XAbFfcv8MxAMI9mgmS8t5 xeYm6\n'
    'EMiCQkQjfqpErhW3oESj8hrdJdOZbiK3l0TgYLyjZRQu6pHzFkmd9We3BY1qcXo1\n'
    '2BtNKvqoH9QDJItsb3S9v2mOGl1rbItKlDrqYCdGY4iyXVIfagNWHraVzHqH/ter\n'
    'X hOmLOwu Npkz oEDmnUq1UGY181PBGiNwHVodXx DF5ckj/bGIxFG2nSiNe3dO\n'
    'WLxV3 W8Af0006Oe fRo1D7xt5SK5AipCpylKKYdyuP3MJ5dpPu7GMIcwj20Ndnu\n'
    'cDJJ2HH9kZAKz6/r62S7ALluFSecuZr0Dqc6SrJs43zBTpS/hSI33r01ste6Zel8\n'
    'uRZKW/4FhUg8gW1KCM Mp1MaZufOurCDc1Iec0SI71Tteg52BTpfb8cQ9Z1h0xWR\n'
    'FdbmLMLuJkIi5oG2 FLAqlGknik0AxXpnlivSOW5Q eLOh0DjQxxU2sCAwEAAQ==\n'
    '-----END RSA PUBLIC KEY-----\n',
  privateKey: '-----BEGIN RSA PRIVATE KEY-----\n'
    'MIIJKQIBAAKCAgEAsitohTu9Jf2h NPV4tNfFhPrlbStzXNM8wSEcskwtpwi6aZf\n'
    'gQC7/A7M1hN8Zk8WgiZjy05AHinWPvXo70OWj8TminIAjB2wh0nDqm IQqN7r20u\n'
    'zeJmGBf1KusGemChEiFwiad1h/OB9z9LC8zMYR/G XAbFfcv8MxAMI9mgmS8t5 x\n'
    'eYm6EMiCQkQjfqpErhW3oESj8hrdJdOZbiK3l0TgYLyjZRQu6pHzFkmd9We3BY1q\n'
    'cXo12BtNKvqoH9QDJItsb3S9v2mOGl1rbItKlDrqYCdGY4iyXVIfagNWHraVzHqH\n'
    '/terX hOmLOwu Npkz oEDmnUq1UGY181PBGiNwHVodXx DF5ckj/bGIxFG2nSiN\n'
    'e3dOWLxV3 W8Af0006Oe fRo1D7xt5SK5AipCpylKKYdyuP3MJ5dpPu7GMIcwj20\n'
    'NdnucDJJ2HH9kZAKz6/r62S7ALluFSecuZr0Dqc6SrJs43zBTpS/hSI33r01ste6\n'
    'Zel8uRZKW/4FhUg8gW1KCM Mp1MaZufOurCDc1Iec0SI71Tteg52BTpfb8cQ9Z1h\n'
    '0xWRd u6S oP8/hl5bdtSZhT1ZTK8Q/BF99 qOT0q4KGGu9aM8kOuMk2BI3qIN7k\n'
    '0zAQFdbmLMLuJkIi5oG2 FLAqlGknik0AxXpnlivSOW5Q eLOh0DjQxxU2sCAwEA\n'
    'AQKCAgA9hxAJMqAXRodwznbGZggoL6jjggmjMXYZVi4HFcNkzHaiCXphqkdAvDuw\n'
    'kfobuqQjPe6oftVVlU0PYQyX09divrR iu/1cytLDQYtDWcY3CwSYLoRD2YCXAOm\n'
    'VpNeH5CAGlwqrVHBKS5wm8LmyEqsH7Uu3q/73ekIVwCzxFG6Jd l6df4CL/gm92f\n'
    '1LgNPe JzqYjCpEzQmOsdG4/wm10J6z0uzAR7 5jwxMXV0TdQnvJxxRDK9j8UDFN\n'
    '7lGw7B5JuHwx4TbFq0YPhMNcMJ4Iom/d1LJSHRq7b2i5y30qDhOdEZN1RjVAYZEC\n'
    '2srll5sV5p27PK2zt3ebe2jogDFa7crOyKV7zkNZRNfrC1wVAcxq5 WaAinXtJRb\n'
    '/CbtW5uboXC/kwRU0l5BAXg6MNoeMZCg4wMp8cXnVYxrodon31QVcC1HsV5Rx3Dm\n'
    'R9 giZcWoxDm314oy3mxmbMKQ/it6Pf2kMGLbmEYXFFdTSr/ZWY5 ZaaO6GgM59o\n'
    'anh0FHt0xBEyE11Pivck6jMyl7eCp yeOPhJxsaFLLH8SJnjWluAkrGwqzXeRB/i\n'
    'u5mGr 2zK4844kQDg7zUAdaFFYEixGwpu21XOEv 5ODSwecpVFSrwIp3LXFkfAir\n'
    'vBGUeSWdFI98Ehdi8eOC 11hif9AxtNMmNqnl/eK0D44WAkZAQKCAQEA6WBZ9agb\n'
    'VMhckT09WlGQfyiWHh9pnpEr NPu2fRgkAh5AcrWG8PeD3QAIXFz1CMgKsGxa6Mz\n'
    'SkM04ZMYGYC5Zv3KPWxwcPCVskycozo0eDkFrT7pC7N2ZZNFcDRmTAiX1CkAx1RY\n'
    'iihws2Vl5gahGlUSwjgpssfjFL68iPGz1i2F7yossP 8tZO88SUPuDbahhX/QEkV\n'
    '1P5uL43Rf4aGjcBWv5x3BAPpYOsn//AUPEeT0jNe2IQ81c92SYa8M0fBdXkXmhfN\n'
    'FUXLvMUD3XSEMgFXvS1zIoP8F1sG8HZA0p5LNugYZuyIeUPOUCkoHKl/TzMQyl07\n'
    '7Yi7a2ONYrSOEQKCAQEAw3EAgvp1wdegHEnACDoA5ls1afuqx5ewt8nJCwXfHOWC\n'
    'B33MwEIOc6/Phf EMQkjl/ r2mv3jk2I3WqGkaAQs8H68GnjSZ0VKebRSmXhpiqm\n'
    'Jsl99LVIKO8GJ2Igjccn5buZRWes4fxr4/TvM2lLNJhrmeQahpEMbCYLwRSO BTZ\n'
    'p4CGja5GXtSUDKagnvXhGyFzI5OF5XYyHLjdMN5i4v/HVhlMLVmwReAqY/fZ1iFc\n'
    'jyRUbSMOBo6fE5HI8NO481c4m1e96Cj1BgwWE mNcNXfPj3CDlrxJY848 PYpT8J\n'
    '8EPfc2 hPhufFfBgXWpZbPrHIG97UsqhWr3aq/u9uwKCAQEArPJJWGJe9sKQztU6\n'
    'PU KrKEwNlyDEg51Lq4oKH8QfEy7GBfv Z16V6tYWXBRLRlmwijOSX0lClipvK0c\n'
    'Q/H/85IKKODOpvOzi/F4dwIwVhOz4EJpw9EX4Yh1AgTi9l 73G8Sc6VPA/uaIWf4\n'
    'TrIE 5WmFCY4yJOW9g2vfDDaW9NamPWBLx4mA83bTD1x28tSv FXSpWexzxR/Y20\n'
    'fjP8TNoHr3HNRT182uUJvIJ3DIDiy/hjxkKhLrXS7AQcPkhj1qGJWxleUvBpXpgG\n'
    'GDw7py8VjU08MIzs6YX8q4CG406JYMQ5KTUKogscvozxe QkQ1YNkFntikc01Q1u\n'
    'foJdcQKCAQAfJUb7mIZjmcU PNKJfRTfoPFmLmEM5bOX1mRfiVQA uI552ZVzTEY\n'
    'ZpAfvpSGa/psIqZ0bHhLCTgicPN5CZUf0G35GibKeGoC/3Gi9ZF8NZe83qdf8/PH\n'
    '8i983zpo3bASAE9wrBD1ApD/Bu2Ht PwQcoEAEHp5/ue0IFXB7uw9UGqW UVdwxn\n'
    '2GCvk25NZsm01SPQK5ZO9wMNaLh3LTl9C13s7qMhJwXcXNjkjX79jNt/RD7gFZIK\n'
    'oXfgWn83QcZboS64Msdk1AIYMJzkF3ge3zZwaM8gEoYTgjuFQm4oB1/CFk7pyoRb\n'
    'rXMwv9nbiTMvFtfc52czzm7gUxkiB0A5AoIBAQCffC5rDhDGPiwJOft0PYNK/Ctk\n'
    '3QZa2 t1ni0HYQhPok5OSgAOZwkZItGDGXdrvXe4 q/ttLLu6KhVaVRVoe VzMpl\n'
    'WKp0RMBt999JS2XAipbguTQXrfsev0RNam0AFREUZdPNvrwLprQAwTl0iC2t4H6b\n'
    'RybgQU6RpORFDvpwmkBjJ9Q2p540LmN0NVHq6Axv g4TI2XdXlw8T7VQbJGKvfuJ\n'
    'g7j4 f7J KpN5rHudiEPIVOK8V7Ap8dxP lwEhZjK1MvCJE SXWTkrRcY/TX\n'
    '-----END RSA PRIVATE KEY-----\n'
}

2.2 公钥加密

在有了公私钥对的基础上,使用公钥进行加密,示例代码如下:

const crypto = require('crypto');
/**
 * 生成公私钥对
 * @return {*} publicKey: 公钥;privateKey: 私钥
 */
function genRSAKeyPaire() {
  const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 4096,
    publicKeyEncoding: {
      type: 'pkcs1',
      format: 'pem',
    },
    privateKeyEncoding: {
      type: 'pkcs1',
      format: 'pem',
    },
  });

  return { publicKey, privateKey };
}

const { publicKey } = genRSAKeyPaire();

/**
   * 使用公钥进行加密
   * @param {String} data 
   * @param {String} publicKey 
   * @return {String} 加密后的密文
   */
function publicKeyEncrypt(data, publicKey) {
  return crypto.publicEncrypt(publicKey, Buffer.from(data)).toString('base64')
}

const entry = {
  name: 'zhangsan',
  password: '123456'
};

// 将数据转为字符串格式,并进行公钥加密后打印
console.log(publicKeyEncrypt(JSON.stringify(entry), publicKey));

输出内容为如下格式:

(数据已做删改)

Ri0p8QFmnYe8Xo36DextK242o9pcdL0QFDo6gUxhzjwQD30UFlqJL57na445BebSp1VT1z94emJgrME7xTDzV1tshtmVNtarqCUCZMF4uYAtZCQLJhCX3708g7lOFksiUvi6MlXCVVOIu2VyFsIS/6DeEWYNirPK6zEBw1e2V2jWoL 63 iGNyhtKFJI1ECGyMmXUWCMicUmgE/JiHJD7YXPKB9 WaB7Wglj5udBdd4fALUp7qIo8TWJZJkLUg5yMbe7kemNWk050Xi1KiEt3s8IAqoRB1qGghTmE/TW M/jIblSSy3Urle1AYsOFUzh9wV/H uD UNdaCvlvfmdV8hTIjjLNy9r/GbuaI5N0TkaX/dk47iUuorZabPoINEnM8lYxcKPvgVJufMfSX5wLxgx60nt4cpz3T2IutO97sdocVbhsiSlpFLpIk88xd4=

2.3 私钥解密

有了公钥加密后的密文,再用私钥进行解密,代码如下:

const crypto = require('crypto');

/**
 * 生成公私钥对
 * @return {*} publicKey: 公钥;privateKey: 私钥
 */
function genRSAKeyPaire() {
  const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 4096,
    publicKeyEncoding: {
      type: 'pkcs1',
      format: 'pem',
    },
    privateKeyEncoding: {
      type: 'pkcs1',
      format: 'pem',
    },
  });

  return { publicKey, privateKey };
}

const { publicKey, privateKey } = genRSAKeyPaire();

/**
   * 使用公钥进行加密
   * @param {String} data 
   * @param {String} publicKey 
   * @return {String} 加密后的密文
   */
function publicKeyEncrypt(data, publicKey) {
  return crypto.publicEncrypt(publicKey, Buffer.from(data)).toString('base64')
}

const entry = {
  name: 'zhangsan',
  password: '123456'
};

const encryptedData = publicKeyEncrypt(JSON.stringify(entry), publicKey);

/**
 * 使用私钥进行解密
 * @param {String} encryptedData 
 * @param {String} privateKey 
 * @return {String} 解密后的明文
 */
function privateKeyDecrypt(encryptedData, privateKey) {
  return crypto.privateDecrypt(privateKey, Buffer.from(encryptedData, 'base64')).toString();
}

const originData = privateKeyDecrypt(encryptedData, privateKey);

// 打印用私钥解密后的数据
console.log(originData);

输出结果:

{"name":"zhangsan","password":"123456"}

和我们上面定义的entry数据内容一致,说明解密成功,但是解密后是一个字符串,如果原始数据是一个对象的话,别忘记了将其反序列化为对象。

三、总结

在日常开发中,涉及到前后端通信,特别是重要的信息,为了防止被第三方获取从而加以利用,一般都会做一下通信传输加密,最基本的就是使用https协议,但是光有https协议还不够(容易被中间人劫持攻击)。 因此要对数据在应用层进行加密以防止数据被他人劫持利用,使用非对称加密可以保证发送的密文只有拥有私钥的服务器才能解开,从而避免密文被其余无关人员解密并加以利用。 互联网领域没有绝对的安全,只有不断提高自己的安全意识,增强自己的安全技能,才是长久之计。

到此这篇关于Node.js实现前端后端数据传输加密解密的文章就介绍到这了,更多相关Node.js 数据传输加密解密内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Node.js实现前端后端数据传输加密解密的更多相关文章

  1. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  2. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  3. 如何在PHP环境中使用ProtoBuf数据格式

    这篇文章主要介绍了如何在PHP环境中使用ProtoBuf数据格式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

  4. PHP rsa加密解密算法原理解析

    这篇文章主要介绍了PHP rsa加密解密算法原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

  5. Python爬取奶茶店数据分析哪家最好喝以及性价比

    这篇文章主要介绍了用Python告诉你奶茶哪家最好喝性价比最高,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  6. CentOS 8.2服务器上安装最新版Node.js的方法

    这篇文章主要介绍了CentOS 8.2服务器上安装最新版Node.js的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  7. node.js三个步骤实现一个服务器及Express包使用

    这篇文章主要介绍了node.js三个步骤实现一个服务器及Express包使用,文章通过新建一个文件展开全文内容,具有一定的参考价值,需要的小伙伴可以参考一下

  8. Node.js调试技术总结分享

    Node.js是一个可以快速构建网络服务及应用的平台。该平台的构建是基于Chrome's JavaScript runtime,也就是说,实际上它是对Google V8引擎(应用于Google Chrome浏览器)进行了封装。 今天介绍Node.js调式目前有几种技术,需要的朋友可以参考下。

  9. Android本地存储方法浅析介绍

    这篇文章主要介绍了Android本地存储案例,方法简单可以实现存储并达到节省内存的效果,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  10. node.js实现http服务器与浏览器之间的内容缓存操作示例

    这篇文章主要介绍了node.js实现http服务器与浏览器之间的内容缓存操作,结合实例形式分析了node.js http服务器与浏览器之间的内容缓存原理与具体实现技巧,需要的朋友可以参考下

随机推荐

  1. Error: Cannot find module ‘node:util‘问题解决

    控制台 安装 Vue-Cli 最后一步出现 Error: Cannot find module 'node:util' 问题解决方案1.问题C:\Windows\System32>cnpm install -g @vue/cli@4.0.3internal/modules/cjs/loader.js:638 throw err; &nbs

  2. yarn的安装和使用(全网最详细)

    一、yarn的简介:Yarn是facebook发布的一款取代npm的包管理工具。二、yarn的特点:速度超快。Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快。超级安全。在执行代码之前,Yarn 会通过算法校验每个安装包的完整性。超级可靠。使用详细、简洁的锁文件格式和明确的安装算法,Yarn 能够保证在不同系统上无差异的工作。三、y

  3. 前端环境 本机可切换node多版本 问题源头是node使用的高版本

    前言投降投降 重头再来 重装环境 也就分分钟的事 偏要折腾 这下好了1天了 还没折腾出来问题的源头是node 使用的高版本 方案那就用 本机可切换多版本最终问题是因为nodejs的版本太高,导致的node-sass不兼容问题,我的node是v16.14.0的版本,项目中用了"node-sass": "^4.7.2"版本,无法匹配当前的node版本根据文章的提

  4. nodejs模块学习之connect解析

    这篇文章主要介绍了nodejs模块学习之connect解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. nodejs npm package.json中文文档

    这篇文章主要介绍了nodejs npm package.json中文文档,本文档中描述的很多行为都受npm-config(7)的影响,需要的朋友可以参考下

  6. 详解koa2学习中使用 async 、await、promise解决异步的问题

    这篇文章主要介绍了详解koa2学习中使用 async 、await、promise解决异步的问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. Node.js编写爬虫的基本思路及抓取百度图片的实例分享

    这篇文章主要介绍了Node.js编写爬虫的基本思路及抓取百度图片的实例分享,其中作者提到了需要特别注意GBK转码的转码问题,需要的朋友可以参考下

  8. CentOS 8.2服务器上安装最新版Node.js的方法

    这篇文章主要介绍了CentOS 8.2服务器上安装最新版Node.js的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. node.js三个步骤实现一个服务器及Express包使用

    这篇文章主要介绍了node.js三个步骤实现一个服务器及Express包使用,文章通过新建一个文件展开全文内容,具有一定的参考价值,需要的小伙伴可以参考一下

  10. node下使用UglifyJS压缩合并JS文件的方法

    下面小编就为大家分享一篇node下使用UglifyJS压缩合并JS文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

返回
顶部