目录

  • 一、编码和解码字符串
  • 二、base64 加密
    • 1、安装
    • 2、使用
      • (1)、node 中使用 js-base64
      • (2)、es6+ 使用 js-base64
  • 三、MD5 加密(不可逆)
    • 1、安装
    • 2、使用
      • (1)、node 中使用 blueimp-md5
      • (2)、es6+ 使用 blueimp-md5
      • (3)、md5 强化加密
  • 四、sha1 加密(不可逆)
    • 1、安装
    • 2、使用
      • (1)、node 中使用 js-sha1
      • (2)、es6+ 使用 js-sha1
  • 五、sha256 加密(不可逆)
    • 1、安装
    • 2、使用
      • (1)、node 中使用 js-sha256
      • (2)、es6+ 使用 js-sha256
  • 六、AES 加密和 DES 解密(对称加密)
    • 1、安装
    • 2、使用
      • (1)、node 中使用 crypto-js
      • (2)、es6+ 使用 crypto-js
  • 七、RSA 加密(非对称加密)
    • 1、安装
      • (1)、前端安装 jsencrypt
      • (2)、后端安装 node-rsa
    • 2、使用
      • (1)、node 中使用 node-rsa
      • (2)、es6+ 使用 jsencrypt
  • 八、JWT 加解密
    • 1、创建加密的 token
    • 2、解析加密的 token

一、编码和解码字符串

javaScript 提供了一些内置方法来实现加密解密。

加密:

  • escape():对字符串进行编码。
  • encodeURI():把字符串编码为 URI。
  • encodeURIComponent():把字符串编码为 URI 组件。

解密:

  • unescape():对由 escape() 编码的字符串进行解码。
  • decodeURI():对由 encodeURI() 编码的 URI 进行解码。
  • decodeURIComponent():对由 encodeURIComponent() 编码的 URI 组件进行解码。

二、base64 加密

需要安装使用 js-base64 插件。

1、安装

yarn add js-base64
// 或者
npm install js-base64 -S

2、使用

(1)、node 中使用 js-base64

var Base64 = require('js-base64').Base64;
Base64.encode('qwerr1123');

(2)、es6+ 使用 js-base64

import { Base64 } from 'js-base64';
Base64.encode('qwerr1123');// 编码
Base64.decode(str);// 解码

更多使用案例,请看官网。

【拓展】
从 IE10+ 浏览器开始,所有浏览器就原生提供了 Base64 编码、解码方法,不仅可以用于浏览器环境,Service Worker环境也可以使用。
浏览器对原生提供的 Base64编码、解码方法:

  • 编码:atob() 方法。
  • 解码:btoa() 方法。

使用 atob() 和 btoa() 方法加密解密:

window.btoa('qwerr1123') // 编码
window.atob(str) // 解码

三、MD5 加密(不可逆)

MD5 加密理论上是不能破解的,因为 MD5 是一种散列函数,使用的是hash算法。

需要安装使用 blueimp-md5 插件。

1、安装

yarn add blueimp-md5
// 或者
npm install blueimp-md5 -S

2、使用

(1)、node 中使用 blueimp-md5

const md5 = require("blueimp-md5");
md5("qwerr1123");

(2)、es6+ 使用 blueimp-md5

import md5 from 'blueimp-md5';
md5("qwerr1123");

(3)、md5 强化加密

如果觉得加密程度不够的话,可以再次嵌套一个md5加密,例如:

md5(md5("qwerr1123"));

【拓展】
“可逆与不可逆”之数学类比:
可逆:

100 (/2) = 50
50 (*2) = 100

不可逆:

100 (%49) = 2

上面这个不可逆的案例之所以是不可逆的,是因为:51、100、149、198 对 49 取余都得 2。在操作过程中某些信息丢失了,因此没法逆向操作以还原。

四、sha1 加密(不可逆)

SHA 系列加密,采用散列算法,并非加密算法,所以不可逆。

需要安装使用 js-sha1 插件。

1、安装

yarn add js-sha1
// 或者
npm install js-sha1 -S

2、使用

(1)、node 中使用 js-sha1

const sha1 = require('js-sha1');
sha1("qwerr1123");

(2)、es6+ 使用 js-sha1

import { sha1 } from 'js-sha1';
sha1("qwerr1123");

五、sha256 加密(不可逆)

SHA 系列加密,采用散列算法,并非加密算法,所以不可逆。

sha256 加密包括:

  • RS256 (采用SHA-256 的 RSA 签名) 是一种非对称算法, 它使用公共/私钥对: 标识提供方采用私钥生成签名, JWT 的使用方获取公钥以验证签名。由于公钥 (与私钥相比) 不需要保护, 因此大多数标识提供方使其易于使用方获取和使用 (通常通过一个元数据URL)。
  • HS256 (带有 SHA-256 的 HMAC 是一种对称算法, 双方之间仅共享一个 密钥。由于使用相同的密钥生成签名和验证签名, 因此必须注意确保密钥不被泄密。

使用 sha256 加密,需要安装使用 js-sha256 插件。

1、安装

yarn add js-sha256
// 或者
npm install js-sha256 -S

2、使用

(1)、node 中使用 js-sha256

var sha256 = require('js-sha256');
sha256('qwerr1123');

(2)、es6+ 使用 js-sha256

import { sha256, sha224 } from 'js-sha256';
sha256('qwerr1123');

六、AES 加密和 DES 解密(对称加密)

需要安装使用 crypto-js 插件。

AES 的加密模式 5 种:

  • ECB:电子密码本模式。
  • CBC:加密分组链接模式。
  • CFB:加密反馈模式。
  • OFB:输出反馈模式。
  • CTR:计数器模式。

AES 的填充 6 种:

  • NoPadding:不填充。
  • PKCS#5:缺几个字节就填几个缺的字节数。
  • PKCS#7:缺几个字节就填几个缺的字节数。
  • ISO 10126:最后一个字节是填充的字节数(包括最后一字节),其他全部填随机数。
  • ANSI X9.23:跟ISO 10126很像,只不过ANSI X9.23其他字节填的都是0而不是随机数。
  • ZerosPadding:全部填充0x00,无论缺多少全部填充0x00,已经是128bits倍数仍要填充。

【拓展】关于AES 的加密模式和填充本文只做了解,若要深入学习 AES 的加密模式和填充,请戳这里。

1、安装

yarn add crypto-js
// 或者
npm install crypto-js -S

2、使用

(1)、node 中使用 crypto-js

var CryptoJS = require("crypto-js");
// Encrypt
var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123').toString();
// Decrypt
var bytes  = CryptoJS.AES.decrypt(ciphertext, 'secret key 123');
var originalText = bytes.toString(CryptoJS.enc.Utf8);
console.log(originalText); // 'my message'

(2)、es6+ 使用 crypto-js

import CryptoJS from "crypto-js";// 若后端没有提供“秘钥”和“常量”,那就分别给定一个默认值。
var key = CryptoJS.enc.Latin1.parse("秘钥"); // 秘钥(后端提供)
var iv = CryptoJS.enc.Latin1.parse("常量");  // 常量(后端提供)export default {//加密encrypt(data) {var srcs = CryptoJS.enc.Utf8.parse(data);var encrypted = CryptoJS.AES.encrypt(srcs, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.ZeroPadding});return encrypted.toString();},//解密decrypt(encrypted) { var decrypted = CryptoJS.AES.decrypt(encrypted, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.ZeroPadding});return decrypted.toString(CryptoJS.enc.Utf8);}
}

七、RSA 加密(非对称加密)

使用场景:前端是利用jsencrypt.js去加密,后端利用node-rsa去生成公私钥并解密。

若前端使用 RSA 加密,需要安装使用 jsencrypt 插件。
若后端使用 DSA 解密,需要安装使用 node-rsa 插件。

1、安装

(1)、前端安装 jsencrypt

yarn add jsencrypt
// 或者
npm install jsencrypt -S

(2)、后端安装 node-rsa

yarn add node-rsa
// 或者
npm install node-rsa -S

2、使用

(1)、node 中使用 node-rsa

const NodeRSA = require('node-rsa');// 生成及导入导出秘钥
var key = new NodeRSA({b: 512}); //生成512位秘钥
var pubkey = key.exportKey('pkcs8-public'); //导出公钥
var prikey = key.exportKey('pkcs8-private'); //导出私钥
var pubKey = new NodeRSA(pubKey, 'pkcs8-public'); //导入公钥
var priKey = new NodeRSA(priKey, 'pkcs8-private'); //导入私钥// 公钥加密(返回密文)
pubKey = new NodeRSA(publicKey, 'pkcs8-public');
var encrypted = pubKey.encrypt(buffer, 'base64');// 私钥解密(返回明文)
priKey = new NodeRSA(privateKey, 'pkcs8-private');
var decrypted = priKey.decrypt(buffer, 'utf8');// 私钥签名(返回签名)
priKey = new NodeRSA(privateKey, 'pkcs8-private');
var signature = priKey.sign(buffer);// 公钥验证(返回true或false)
pubKey = new NodeRSA(publicKey, 'pkcs8-public');
var flag = pubKey.verify(buffer, signature);

(2)、es6+ 使用 jsencrypt

import JSEncrypt from 'jsencrypt';const jsencrypt = new JSEncrypt();// 创建 JSEncrypt 对象实例// 加密
const publicKey = `-----BEGIN PUBLIC KEY-----... ...`;// 加密公钥
export function setEncrypt (msg) {jsencrypt.setPublicKey(publicKey);// 设置公钥return jsencrypt.encrypt(msg);// 对内容进行加密
}
// 解密
const privateKey  = '-----BEGIN RSA PRIVATE KEY-----';// 解密私钥
export function decrypt (msg) {decrypt.setPrivateKey(privateKey);// //设置秘钥return decrypt.decrypt(msg);// 解密之前拿公钥加密的内容
}

八、JWT 加解密

JWT 全称 JSON WEB TOKEN。
JWT 先 Base64 编码对其头部进行加密,然后采用 HS256 算法进行加密。

JWT的构成:

  • 第一部分我们称它为头部(header);
  • 第二部分我们称其为载荷(payload, 类似于飞机上承载的物品);
  • 第三部分是签证(signature)。

公共的声明 :
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密。

私有的声明 :
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

JWT的优点:

  • 因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用。
  • 因为有了payload部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息。
  • 便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。
  • 它不需要在服务端保存会话信息, 所以它易于应用的扩展。

JWT的注意事项:

  • 不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解密的部分。
  • 保护好secret私钥,该私钥非常重要。
  • 如果可以,请使用https协议。

1、创建加密的 token

// 创建一个 token
export const createToken = (params) => {// secret——加密密文,私钥;expires——到期时间(秒)const { secret, expires } = tokenBaseInfo;const token = JWT.sign({// id: params.id ...timestamp: (new Date()).getTime()}, secret, {expiresIn: expires});return token;
}

2、解析加密的 token

// 解析 token
export const resolveToken = (token) => {// secret——加密密文,私钥const { secret } = tokenBaseInfo;return new Promise((resolve, reject) => {JWT.verify(token, secret, (error, data) => {error ? reject(error) : resolve(data);});})
}

参考文档:
前端js几种加密/解密方法:https://www.jianshu.com/p/4c236d83ea04
AES加密解密前端使用方法:https://blog.csdn.net/qq_37135762/article/details/111321321
AES加密(3):AES加密模式与填充:https://zhuanlan.zhihu.com/p/131324301
使用JSEncrypt加密解密:https://www.cnblogs.com/hlweng-0207/p/12971180.html
前端利用jsencrypt.js进行RSA加密:https://www.jianshu.com/p/5008a407b558
基于node简单实现RSA加解密的方法步骤:https://www.jb51.net/article/158197.htm
node-rsa使用:https://www.appblog.cn/2017/10/23/node-rsa%E4%BD%BF%E7%94%A8/
什么是 JWT – JSON WEB TOKEN:https://www.jianshu.com/p/576dbf44b2ae
JSON Web Token – 在Web应用间安全地传递信息:http://blog.leapoahead.com/2015/09/06/understanding-jwt/