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