Node.js实现前端后端数据传输加密解密

目录
  • 一、简介
  • 二、示例
    • 2.1 生成公私钥对
    • 2.2 公钥加密
    • 2.3 私钥解密
  • 三、总结

一、简介

在前后端通信过程中,一些敏感信息,特别是用户的账号密码,需要加密进行传输,如何选择加密方式也是一门学问,这里倒也不过多偏题了。 通常来说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' +
    '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\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 数据传输加密解密内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Node.js 数据加密传输浅析

    前言 数据加密传输,大家经常接触几个方式一个是密文传输,一个明文传输密文传输,就是用密钥对数据加密,使用公钥对数据解密,传输的通道可以是https的也可以是http的.明文传输,前提是建立一个安全的传输通道,这里使用证书对通道的安全做了防护,然后传输数据,使用的是明文. 比较专业的 可以后面慢慢分享,不过这里我就介绍下明文传输,如果是用nodejs建立安全通道 使用两个库,分别是urllib和request,这里的证书只介绍使用pfx文件 urllib库的方式 const urllibReque

  • Java与Node.js利用AES加密解密出相同结果的方法示例

    前言 工作中遇到nodejs端通过aes加密,安卓客户端Java解密,同样nodejs也需要解密安卓客户端加密过来的内容,发现两个加密结果不一样,查询资料发现java端需要对密钥再MD5加密一遍,以下是Java与Node.js利用AES加密解密出相同结果的方法,需要的朋友们下面来一起学习学习吧. JAVA代码如下: package g.g; import java.security.MessageDigest; import javax.crypto.Cipher; import javax.c

  • Node.js实现前端后端数据传输加密解密

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

  • 基于 Node.js 实现前后端分离

    基本介绍 首先从一个重要的概念"模板"说起. 广义上来说,web中的模板就是填充数据后可以生成文件的页面. 严格意义上来说,应该是模板引擎利用特定格式的文件和所提供的数据编译生成页面.模板大致分为前端模板(如ejs)和后端模板(如freemarker)分别在浏览器端和服务器端编译. 由于当场有一部分同学对node.js并不是很了解,这里补充一下node.js的相关知识.官网上的给他的定义事件驱动.异步什么的就不说了.这里借用朴灵书上的一张图来解释一下node.js这个玩意的结构.如果懂

  • 原生js的RSA和AES加密解密算法

    本文实例为大家分享了js中RSA和AES加密解密详细代码,供大家参考,具体内容如下 <!doctype html> <html> <head> <meta charset='UTF-8'> </head> <body> <div class='test'></div> <script type="text/javascript"> function encrypt(data, k

  • JS使用插件cryptojs进行加密解密数据实例

    本文实例讲述了JS使用插件cryptojs进行加密解密数据.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Testing websoc

  • 使用node.js对音视频文件加密的实例代码

    废话不多说了,直接给大家贴代码了,具体代码如下所示: fs.readFile('./downsuccess/'+name+'', {flag: 'r+', encoding: ''}, function (err, data) { console.log('读取中') if(err) { return; } let b = new Buffer(data); let c = b.toString('hex'); let cipherBuffer = _this.cipher(data); fs.

  • JS实现的3des+base64加密解密算法完整示例

    本文实例讲述了JS实现的3des+base64加密解密算法.分享给大家供大家参考,具体如下: 1. index.html: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>www.jb51.net BASE64编码</title> <meta http-equiv="Content-Type" content="text/html; c

  • 同时兼容JS和C#的RSA加密解密算法详解(对web提交的数据加密传输)

    前言 我们在Web应用中往往涉及到敏感的数据,由于HTTP协议以明文的形式与服务器进行交互,因此可以通过截获请求的数据包进行分析来盗取有用的信息.虽然https可以对传输的数据进行加密,但是必须要申请证书(一般都是收费的),成本较高.那么问题来了,如果对web提交的敏感数据进行加密呢?web应用中,前端的数据处理和交互基本上都是靠javascript来完成,后台的逻辑处理可以C#(java)等进行处理. 微软的C#中虽然有RSA算法,但是格式和OpenSSL生成的公钥/私钥文件格式并不兼容.这个

  • Node.js获取前端ajax提交的request信息

    今天看一下Node.js怎么获取ajax提交的request 信息 众所周知,ajax可以在不刷新整个页面的情况下实现局部刷新,这是相当好的一种方式,能够让我们动态更新信息,今天我们看一下怎么用node来接收到前端ajax提交过来的信息 下面我贴一下前端的代码 index.html的代码我就不贴了, 因为里面就只有一个按钮而已,要实现的功能是点击按钮提交ajax异步请求 主要贴一下js页面的代码 $("button").on("click",function(){

  • 浅谈如何通过node.js对数据进行MD5加密

    md5介绍:MD5是一种常用的哈希算法,主要用于对一些重要数据进行"签名",当然这些数据可以是任意的.最终得到的"签名"通常都是一个16或32位的十六进制的字符串. 实际工作开发中,是不会有人直接将密码明文直接放到数据库当中的.因为这种做法是非常不安全的,一般都要对其进行MD5加密!比如某用户的密码是"123456"(当然这样的密码也没有安全性可言),经过MD5处理后即为: "e10adc3949ba59abbe56e057f20f88

  • Nginx设置为Node.js的前端服务器方法总结

    1.安装node.js 首先安装node.js安装所需的软件包,并在启动板上添加可用的nodejs的PPA.之后使用以下命令安装nodejs. $ sudo apt-get install python-software-properties python g++ make $ sudo add-apt-repository ppa:chris-lea/node.js $ sudo apt-get update $ sudo apt-get install nodejs 2.安装nginx 现在

随机推荐