在大前端的趋势下,前端er也要懂点数据加密相关的知识才行,加密算法的实现和原理我们可以不用深究,毕竟加密是一门高深的学科,但是基本的加密方式和编码还是要掌握的,毕竟没吃过猪肉,猪跑还是见过的嘛。
我对常见的几种加密和签名的算法做个归纳,同时附上 nodejs 的编码实现。
加密算法
为了保证数据的安全性和防篡改,很多数据在传输中都进行了加密。举个场景的栗子,最近很多网站都升级到 https 协议, https 协议就是使用了非对称加密和hash签名,还有 github 使用的 ssh ,也是非对称加密。还有大部分登录时密码采用的 MD5 加密等等。
加密可分为三大类,对称加密和非对称加密,还有摘要算法,我们一一展开。
对称加密
引用百科的描述:
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。
对称加密很好理解,就好比我把我家的钥匙给你,你要来我家,直接用这把钥匙开门就行。
对称加密目前主流的有 AES 和 DES , AES 是新一代的标准,速度快,安全级别更高。
AES
AES的加密模式有五种:CBC、ECB、CTR、OCF、CFB
ECB:电子密本方式,需要一个密钥即可,特点是简单,利于并行计算。
CBC:密文分组链接方式,除了需要一个密钥之外,还需要一个向量,向量的作用也是用于数据的加密,所以这个的安全性要好于 ECB
CTR、OCF、CFB:具体算法的实现方式不一样,优缺点也各不相同,而这几个都同 CBC 一样,都需要密钥和向量。
AES 有三种长度 128位、192位、256位,这三种的区别,主要来自于密钥的长度,16字节密钥=128位,24字节密钥=192位,32字节密钥=256位。如下表格:
长度
密钥长度
向量长度
128位
16
16
192位
24
16
256位
32
16
DES
加密默认与 AES 相同,也有五种模式,除了 ECB 只需要密钥,其他模式需要密钥和向量。
与 AES 不同的是, DES 的密钥长度只有8字节,向量也是8字节。
编码实现
在 nodejs 中的实现
/** * @description * 对称加密 * @param {*} data 加密数据 * @param {*} algorithm 加密算法 * @param {*} key 密钥 * @param {*} iv 向量 * @returns */ function cipherivEncrypt(data, algorithm, key, iv) { const cipheriv = crypto.createCipheriv(algorithm, key, iv) let encrypted = cipheriv.update(data, 'utf8', 'hex'); encrypted += cipheriv.final('hex'); return encrypted } /** * @description * 对称解密 * @param {*} data 解密数据 * @param {*} algorithm 解密算法 * @param {*} key 密钥 * @param {*} iv 向量 * @returns */ function cipherivDecrypt(data, algorithm, key, iv) { const decipher = crypto.createDecipheriv(algorithm, key, iv); let decrypted = decipher.update(data, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted }
使用官方提供 crypto 库来实现加解密,上面的代码中加密后输出的是 16 进制的字符串,大家可以根据具体情况换成其他格式的数据。
调用方式如下
// AES对称加解密 const str = 'xiaoliye'; const key = 'aaaaaaaaaaaaaaaaaaaaaaaa'; // 24 const iv = 'aaaaaaaaaaaaaaaaaaaaaaaa'; // 24 const cipherAesText = cipherivEncrypt(str, 'aes-192-cfb', key,iv) const resultText = cipherivDecrypt(cipherAesText, 'aes-192-cfb', key,iv) console.log(resultText === str) // true
// DES对称加解密 const str = 'xiaoliye'; const key = 'aaaaaaaa'; //8 const iv = 'aaaaaaaa'; //8 const cipherAesText = cipherivEncrypt(str, 'des-cfb', key,iv) const resultText = cipherivDecrypt(cipherAesText, 'des-cfb', key,iv) console.log(resultText === str) / true
非对称加密
非对称加密,有两把钥匙,公钥和私钥,如下图:
公钥是可以公开对外,私钥就是自个的,不可泄露。因为有两个密钥,非对称加密这个名字就是这么由来的。
发送方用接收方公开对外的公钥进行加密,接收方收到数据后,用私钥进行解密,业务处理完后,用私钥给需要回传的数据加密,收到数据的一方在用公钥解密。
这个过程就是非对称加解密,简单理解就是公钥加密的数据,用私钥解密;私钥加密的数据,用公钥解密。