今天来总结一下常见的加密算法
Base64编码
概念
- 这是一种将二进制数据转换为文本格式的编码方式。它使用 64 个字符(包括字母、数字和部分符号)来表示二进制数据。例如,在电子邮件中,由于传统的 SMTP 协议只支持 ASCII 字符传输,所以当需要传输非 ASCII 字符(如图片、音频等二进制文件)时,Base64 编码就会将二进制数据转换为 ASCII 字符形式,方便传输。
- 在网页中,一些小图标或者简单的二进制数据也会采用 Base64 编码直接嵌入到 HTML 或 CSS 文件中,减少文件获取的请求次数,提高网页加载效率。
实现过程
将二进制数据,以每6个一组重新划分多了几个以0补齐,每一组对应一个字符,从而将二进制数据转化成ASCLL字符方便传输
以下是base64对照表
js代码实现
const s = 'you'
// 将明文转为base64的
const result = Buffer.from(s, 'utf-8').toString('base64')
console.log(result)
// 把base64的编码转为明文
const result1 = Buffer.from(result, 'base64').toString('utf-8')
console.log(result1)
严格来说base64并不是加密算法,因为它没有保密性
哈希算法
基本定义
-
数据转换
- 哈希算法是一种能将任意长度的数据(如文本、文件等)通过特定的计算规则,转换为固定长度的数值序列(哈希值、散列值)的算法。例如,无论你输入的是一个短单词还是一整部长篇小说,哈希算法都能为其生成一个固定长度的哈希值。
-
单向性
- 哈希算法具有单向性,即从原始数据很容易计算出哈希值,但从哈希值几乎不可能逆向推导出原始数据。例如,使用常见的哈希算法对文件进行哈希计算后,即使你知道了文件的哈希值,也极难还原出文件的原始内容
常见的哈希算法
- MD5(Message - Digest Algorithm 5) :它可以将任意长度的数据转换为 128 位的哈希值。不过,由于存在碰撞等安全隐患,现在主要用于数据完整性校验等非安全关键的场景。例如,在简单的文件下载完整性检查中还会用到。
- SHA - 1(Secure Hash Algorithm 1) :产生 160 位的哈希值。但随着技术发展,也被发现存在安全风险。
- SHA - 2(Secure Hash Algorithm 2) :包括 SHA - 224、SHA - 256 等多种变体,是目前应用比较广泛的哈希算法,用于保证数据的完整性和一致性。比如在区块链技术中,SHA - 256 用于验证交易信息等内容的完整性。
在js文件中运用md5算法
//导入模块
const crypto = require('crypto');
//创建md5对象
var obj = crypto.createHash('md5');
obj.update('123456');
console.log(obj.digest('hex'));//十六进制
MD5算法理论上是安全的,它具有单向性(只能从明文转密文,不能从密文转明文),但是密文很容易拿到,假如你暴力破解,用一个程序一个一个试,直到得到一样的密文,在平时输密码的时候输错了几次还会冻结账号,但是这个不会。所以这个算法主要用于数据完整性校验等非安全关键的场景。代码实现大家自己去悟哈,这个说不得。
其他两种也是一样,只需要将md5换一下即可,具体的不做多赘述
对称加密算法
一、定义
对称加密算法,也叫单钥加密算法。在这种加密方法中,加密和解密使用相同的密钥。就好像一把锁和一把钥匙,同一把钥匙既能把锁锁上(加密),又能把锁打开(解密)。
二、原理
-
加密过程
- 发送方使用密钥对明文数据进行加密操作,将明文转换为密文。例如,假设密钥为 K,明文为 M,通过加密算法 E 得到密文 C,公式表示为:C = E (K, M)。
-
解密过程
- 接收方收到密文后,使用相同的密钥 K 对密文进行解密操作,还原出明文。用公式表示为:M = D (K, C),其中 D 是解密算法,且 D 是 E 的逆运算。
三、常见的对称加密算法
-
DES(Data Encryption Standard)
- 它是早期广泛使用的对称加密算法,采用 56 位密钥对 64 位的数据块进行加密。不过随着计算机技术的发展,56 位密钥长度相对较短,其安全性有所降低。
-
3DES(Triple DES)
- 它是 DES 的改进版本,通过三次使用 DES 算法对数据进行加密,有效增加了密钥长度,提高了安全性,但加密速度相对 DES 会慢一些。
-
AES(Advanced Encryption Standard)
- 这是目前应用最为广泛的对称加密算法之一。它可以支持 128 位、192 位或 256 位密钥长度,对 128 位的数据块进行加密。AES 在安全性和加密效率上都有很好的表现,被用于多种领域,如文件加密、网络通信加密等。
4 .它们的主要区别体现在安全性上,DES的密钥长度相对较短,通过暴力破解在一定时间内可能得到正确密钥,DES一次处理64位数据,而AES一次处理128位,AES不管是加密还是解密效率都比DES高
四.加密模式
-
ECB 模式
- 在 EBC 模式下,每个明文分组独立地进行加密。也就是说,相同的明文分组,无论出现在数据的哪个位置,经过加密后都会得到相同的密文分组。例如,若有明文分组为 M1、M2、M3,使用密钥 K 进行加密,加密后的密文分组 C1 = E(K,M1)、C2 = E(K,M2)、C3 = E(K,M3),各密文分组之间没有关联。
-
CBC 模式
- CBC 模式在加密时,每个明文分组在加密前会先与前一个密文分组进行异或操作。第一个明文分组会和一个初始向量(IV,Initial Vector)进行异或。假设初始向量为 IV,明文分组为 M1、M2、M3,密钥为 K,加密过程为:C1 = E(K,M1⊕IV),C2 = E(K,M2⊕C1),C3 = E(K,M3⊕C2)。这样一来,每个密文分组都依赖于前面的密文分组,密文分组之间存在关联
-
CBC比EBC安全性高,因为EBC相同的明文会产生相同的密文分组,这就给攻击者留下了可乘之机。例如,在加密图片这种有大量重复数据的文件时,攻击者可以通过分析密文分组的重复性,推断出明文的一些信息,像图片中的纯色区域可能会在密文中体现出相同的分组模式。而CBC模式,由于密文分组之间存在关联,使得攻击者难以通过分析密文来获取明文的信息。即使明文有重复部分,经过 CBC 模式加密后,密文也不会出现像 EBC 模式那样明显的重复模式,增加了破解的难度。
五.应用(只讲AEC)
CBC模式
// crypto-js
// npm install ctypto-js
// 引入crypto-js库
const CryptoJs = require('crypto-js')
// 要加密的明文
let password = '123456'
// 加密使用的秘钥 加密的秘钥, 16,24,32个字符
let key = '1234567890abcdefg'
// 配置选项 加密模式,填充模式
let cfg = {
// 加密模式: CBC
mode: CryptoJs.mode.CBC,
// 填充方式
padding: CryptoJs.pad.Pkcs7,
// iv是随机生成的数据且是唯一的,iv是第一个明文块进行异或操作以开始加密的过程
iv:CryptoJs.enc.Hex.parse('0000000000000000')
}
// 加密
let encPwd = CryptoJs.AES.encrypt(password, key, cfg).toString()
console.log(encPwd)
// 解密
let result = CryptoJs.AES.decrypt(encPwd, key, cfg).toString(CryptoJs.enc.Utf8)
console.log(result)
ECB模式
// crypto-js
// npm install ctypto-js
// 引入crypto-js库
const CryptoJs = require('crypto-js')
// 要加密的明文
let password = '123456'
// 加密使用的秘钥 加密的秘钥, 16,24,32个字符
let key = '1234567890abcdefg'
// 配置选项 加密模式,填充模式
let cfg = {
// 加密模式: ECB
mode: CryptoJs.mode.ECB,
// 填充方式
padding: CryptoJs.pad.Pkcs7
}
// 加密
let encPwd = CryptoJs.AES.encrypt(password, key, cfg).toString()
console.log(encPwd)
// 解密
let result = CryptoJs.AES.decrypt(encPwd, key, cfg).toString(CryptoJs.enc.Utf8)
console.log(result)
非对称加密算法
举几个例子:
- 当别人想给你发送一个秘密消息(明文)时,就像是给你投递信件。他们可以使用你公开的 “投递钥匙”。这个钥匙可以把信件(明文)放入一个特殊的加密盒子(加密过程),这个盒子一旦锁上(加密完成),就只能用你的 “开启钥匙” 才能打开。
- 以信件为例,你想让别人知道这封信是你发出的,并且没有被篡改。你可以用自己的 “开启钥匙”(私钥)在信件的背面盖一个特殊的印章(数字签名)。这个印章是用你的私钥通过复杂的数学运算生成的,代表了你对这封信的认可。如果别人想验证可以通过你公开的公钥验证,因为只有你的私钥才能生成这个印章。
非对称算法的特点就是安全性高,方便保管私钥,但是,与对称加密算法相比,非对称加密算法的计算过程更为复杂。因为涉及到复杂的数学运算,所以加密速度相对较慢。例如,在加密大量数据(如视频文件)时,非对称加密算法可能会因为速度问题而不太适用。
常见的非对称加密算法
-
RSA(Rivest - Shamir - Adleman)
- 这是最著名的非对称加密算法之一。它的安全性基于大整数分解的困难性。在数字签名、密钥交换等场景中有广泛应用。例如,在网上银行系统中,银行会将公钥提供给用户,用户使用公钥对登录信息等进行加密,银行再用私钥进行解密,确保了信息传输的安全性。
-
DSA(Digital Signature Algorithm)
- 主要用于数字签名。它能够提供数据完整性和不可否认性服务。例如,在电子文档签名场景中,发送方使用自己的私钥对文档的哈希值进行签名,接收方可以使用发送方的公钥来验证签名,确保文档的真实性。
-
ECC(Elliptic Curve Cryptography)
- 基于椭圆曲线数学。它可以用更短的密钥长度达到与 RSA 相当甚至更高的安全级别。在移动设备和物联网设备等资源有限的场景中有很多应用,因为这些设备的计算能力和存储资源有限,ECC 的高效性更符合需求。
应用(只讲一下RSA)
公钥私钥,可以在百度上搜‘RSA公钥私钥在线生成’一般随便点个网站就可以生成,不用自己去生成。uutool.cn/rsa-generat…
代码:
// 安装 npm install jsencrypt
// 使用rsa算法完成加密
window = global
// 引入jsencrypt库
const JSEncrpty = require('jsencrypt')
// 创建JSEncrpty实例
const jse = new JSEncrpty()
// 设置RSA公钥, 假设公钥为一个字符串
const publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGige8RYtenu8ut3Y20pxu5zfW4cKzkebeftdpjuctteh4VRmLyXbrJTKEu0bPs63ToUBtLhwnp841cZglxftRhvT1xjySazlOgV4HgeKcunKytF/RuFaiSYwSTQDCeAq2rcTAByvXMWWFzHn5/BsBozzn3l3rNlf+Cr1+dna+dwIDAQAB'
// 设置公钥 (公钥: 公开的,利用公钥加密 解密: 私钥, 服务器)
jse.setPublicKey(publicKey)
// 要加密的密文
const data = "hello world"
// 加密
const result = jse.encrypt(data)
console.log('加密后的密文是:', result)
const pKey = 'MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIaKB7xFi16e7y63djbSnG7nN9bhwrOR5t5+12mO5y216HhVGYvJduslMoS7Rs+zrdOhQG0uHCenzjVxmCXF+1GG9PXGPJJrOU6BXgeB4py6crK0X9G4VqJJjBJNAMJ4CratxMAHK9cxZYXMefn8GwGjPOfeXes2V/4KvX52dr53AgMBAAECgYB4W6FB76EXu+1TiLLLpqxllpngtUTeKic0YprJBxuPTA41IERjRo8JG9TO408c3qwiCD6/raFoZHlYXE/1cuE5m8saoLEzXtGotRiU9vdyEqK3ZzgrxFzM5Rd32bGfYLHTCbByhuI3mQNjQm0geJDXv+mkBH1+Ok9NKBVZADpKAQJBAPXs15vz5MOW+s76j0AusKih4xJWX1U962E63m703hpkR0fybZTiQzL8atx2JvkrKCzmwFxTPqfQE467VawG0wECQQCMDQT+WFzA2sGqq/qErGllES9xEJTmxvOnZBnOyJ9Tn7iB1aO9Rxvk0+GGKFvUsefgfv+RTNgkt3gEOd7Q/6l3AkB+g6hr522xnVNL9aSKXTqulhHOFjcXEDKuI23Y4Qn9w8bT4Yi0Ri5R5X9ICVSFbMlPSCp/lKewByB4ljE9vYkBAkAwQLwbte4fND/NwftKguy9ObKSzhe/e4Svg7mwmUbr1PgJI8aKjFl7+dSWGImrOrCdlKQRN9ywqdXb/uRaNfv5AkAKwDE/of8vBstc72NrBOQ1B7RXVhW171Al1iazOk56QjRqg/NZCN9j5K8pBcF8O3cJQnMwI2aNyedhHFzSf/Yk'
// 设置私钥 Private
jse.setPrivateKey(pKey)
// 使用私钥进行解密
const result1 = jse.decrypt(result)
console.log(result1)
本文只是简单介绍了一下常见加密算法,并没有详细讲,应用只讲了最常用的。本人大一,如果你觉得我写的还OK,麻烦点个赞吧!