目录

  • 一、编码和解码字符串
  • 二、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);
    });
  })
}