常见的加密算法

597 阅读11分钟

今天来总结一下常见的加密算法

Base64编码

概念

  • 这是一种将二进制数据转换为文本格式的编码方式。它使用 64 个字符(包括字母、数字和部分符号)来表示二进制数据。例如,在电子邮件中,由于传统的 SMTP 协议只支持 ASCII 字符传输,所以当需要传输非 ASCII 字符(如图片、音频等二进制文件)时,Base64 编码就会将二进制数据转换为 ASCII 字符形式,方便传输。
  • 在网页中,一些小图标或者简单的二进制数据也会采用 Base64 编码直接嵌入到 HTML 或 CSS 文件中,减少文件获取的请求次数,提高网页加载效率。

实现过程

将二进制数据,以每6个一组重新划分多了几个以0补齐,每一组对应一个字符,从而将二进制数据转化成ASCLL字符方便传输

以下是base64对照表

image.png

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并不是加密算法,因为它没有保密性

哈希算法

基本定义

  1. 数据转换

    • 哈希算法是一种能将任意长度的数据(如文本、文件等)通过特定的计算规则,转换为固定长度的数值序列(哈希值、散列值)的算法。例如,无论你输入的是一个短单词还是一整部长篇小说,哈希算法都能为其生成一个固定长度的哈希值。
  2. 单向性

    • 哈希算法具有单向性,即从原始数据很容易计算出哈希值,但从哈希值几乎不可能逆向推导出原始数据。例如,使用常见的哈希算法对文件进行哈希计算后,即使你知道了文件的哈希值,也极难还原出文件的原始内容

常见的哈希算法

  • 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换一下即可,具体的不做多赘述

对称加密算法

一、定义

对称加密算法,也叫单钥加密算法。在这种加密方法中,加密和解密使用相同的密钥。就好像一把锁和一把钥匙,同一把钥匙既能把锁锁上(加密),又能把锁打开(解密)。

二、原理

  1. 加密过程

    • 发送方使用密钥对明文数据进行加密操作,将明文转换为密文。例如,假设密钥为 K,明文为 M,通过加密算法 E 得到密文 C,公式表示为:C = E (K, M)。
  2. 解密过程

    • 接收方收到密文后,使用相同的密钥 K 对密文进行解密操作,还原出明文。用公式表示为:M = D (K, C),其中 D 是解密算法,且 D 是 E 的逆运算。

三、常见的对称加密算法

  1. DES(Data Encryption Standard)

    • 它是早期广泛使用的对称加密算法,采用 56 位密钥对 64 位的数据块进行加密。不过随着计算机技术的发展,56 位密钥长度相对较短,其安全性有所降低。
  2. 3DES(Triple DES)

    • 它是 DES 的改进版本,通过三次使用 DES 算法对数据进行加密,有效增加了密钥长度,提高了安全性,但加密速度相对 DES 会慢一些。
  3. 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)

非对称加密算法

举几个例子:

  • 当别人想给你发送一个秘密消息(明文)时,就像是给你投递信件。他们可以使用你公开的 “投递钥匙”。这个钥匙可以把信件(明文)放入一个特殊的加密盒子(加密过程),这个盒子一旦锁上(加密完成),就只能用你的 “开启钥匙” 才能打开。
  • 以信件为例,你想让别人知道这封信是你发出的,并且没有被篡改。你可以用自己的 “开启钥匙”(私钥)在信件的背面盖一个特殊的印章(数字签名)。这个印章是用你的私钥通过复杂的数学运算生成的,代表了你对这封信的认可。如果别人想验证可以通过你公开的公钥验证,因为只有你的私钥才能生成这个印章。

非对称算法的特点就是安全性高,方便保管私钥,但是,与对称加密算法相比,非对称加密算法的计算过程更为复杂。因为涉及到复杂的数学运算,所以加密速度相对较慢。例如,在加密大量数据(如视频文件)时,非对称加密算法可能会因为速度问题而不太适用。

常见的非对称加密算法

  1. RSA(Rivest - Shamir - Adleman)

    • 这是最著名的非对称加密算法之一。它的安全性基于大整数分解的困难性。在数字签名、密钥交换等场景中有广泛应用。例如,在网上银行系统中,银行会将公钥提供给用户,用户使用公钥对登录信息等进行加密,银行再用私钥进行解密,确保了信息传输的安全性。
  2. DSA(Digital Signature Algorithm)

    • 主要用于数字签名。它能够提供数据完整性和不可否认性服务。例如,在电子文档签名场景中,发送方使用自己的私钥对文档的哈希值进行签名,接收方可以使用发送方的公钥来验证签名,确保文档的真实性。
  3. 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,麻烦点个赞吧!