在前后端数据传输、敏感信息存储等场景中,加密是保障数据安全的核心手段。对称加密作为最常用的加密体系之一,以高效、易用的特点广泛应用于各类项目。本文将从基础概念入手,详解对称加密的核心逻辑,对比DES与AES算法的差异,并通过「拆分代码+逐段讲解」的方式,给出JavaScript和Python中可直接运行的AES加密/解密实战代码。

一、对称加密概述

对称加密(Symmetric Encryption)是指加密和解密使用同一把密钥的加密算法体系。其核心逻辑可概括为:发送方用密钥将明文加密为密文,接收方用相同密钥将密文解密为明文。

相比于非对称加密,对称加密的最大优势是加解密效率极高(无需复杂的数学运算),适合处理大量数据(如接口传输的业务数据、文件加密等);但缺点也很明显——密钥的传输和保管存在安全风险(一旦密钥泄露,数据将完全暴露)。

二、对称加密与非对称加密的核心区别

为了更清晰理解对称加密的定位,我们对比它与非对称加密(如RSA)的核心差异:

维度

对称加密(AES/DES)

非对称加密(RSA/ECDSA)

密钥数量

仅1把(加密=解密)

2把(公钥加密,私钥解密)

加解密效率

极高(毫秒级处理海量数据)

较低(适合小数据加密/签名)

密钥传输风险

高(密钥需传输,易被拦截)

低(仅传输公钥,私钥本地保存)

适用场景

大量数据加密(如接口数据、文件)

密钥交换、数字签名(如登录token)

典型算法

AES、DES、3DES、RC4

RSA、ECC、DSA

简单来说:对称加密负责「数据加密」,非对称加密负责「密钥加密」,两者结合是主流的安全传输方案(如HTTPS)。

三、常见对称加密算法

1. DES:经典但已淘汰的对称加密算法

DES(Data Encryption Standard)是1977年发布的经典对称加密算法,采用64位分组长度、56位有效密钥(剩余8位为校验位),属于分组加密算法。

DES加密流程

  1. 明文分组:将明文按64位(8字节)为一组拆分,不足则补位;

  2. 初始置换:对每组明文进行固定规则的位置换,打乱原始顺序;

  3. 16轮迭代加密:每轮用子密钥对数据进行移位、替换、异或操作;

  4. 逆初始置换:对16轮迭代后的结果做反向置换,生成64位密文;

  5. 拼接分组:将所有分组的密文拼接,得到最终密文。

DES的局限性

  • 密钥长度过短(56位):现代计算机可通过暴力破解在短时间内破解密钥;

  • 分组长度小(64位):安全性不足;

  • 已被主流场景淘汰,仅部分老旧系统仍在使用。

2. AES:当前主流的对称加密算法

AES(Advanced Encryption Standard)是2001年取代DES的新一代对称加密标准,也是目前全球应用最广泛的对称加密算法,无专利限制,安全性和效率兼具。

AES核心概念

  • 分组长度固定为128位(16字节);

  • 密钥长度可选:128位(最常用)、192位、256位(安全性更高,需特殊合规);

  • 属于分组加密算法,支持多种工作模式(如ECB、CBC、GCM等)。

AES加密流程

  1. 明文分组:将明文按128位(16字节)为一组拆分,不足则按指定规则补位;

  2. 初始轮:将明文分组与初始密钥进行异或操作;

  3. 多轮变换:根据密钥长度执行不同轮数的变换(128位密钥→10轮,256位→14轮),每轮包含字节代换、行移位、列混合、轮密钥加4个步骤;

  4. 最终轮:去掉列混合步骤,完成最后一轮变换;

  5. 拼接分组:将所有分组的密文拼接,得到最终密文。

AES对比DES的核心优势

  • 密钥长度更长:128/256位密钥远高于DES的56位,暴力破解几乎不可能;

  • 分组长度更大:128位分组比DES的64位更安全;

  • 效率更高:AES的算法设计更简洁,软硬件实现都比DES快;

  • 安全性更高:至今无有效破解方法,是国际公认的安全标准。

四、对称加密的核心工作模式

对称加密算法(如AES)的加密逻辑需要结合「工作模式」才能落地,不同模式决定了分组数据的处理方式,其中最基础的是ECB和CBC模式。

1. ECB模式(电子密码本模式)

  • 核心逻辑:将明文分组独立加密,每组的加密结果仅依赖自身和密钥;

  • 优点:简单易实现,支持并行加密;

  • 缺点:相同明文分组会生成相同密文分组,易被攻击者分析规律(如重复的密文分组可推断明文内容);

  • 适用场景:仅适合加密短且无规律的小数据,不推荐用于业务数据加密

2. CBC模式(密码分组链接模式)

  • 核心逻辑:前一个分组的密文会作为后一个分组的「初始化向量(IV)」参与加密,第一个分组需指定固定IV;

  • 优点:相同明文分组会生成不同密文分组,安全性远高于ECB;

  • 缺点:需额外传递IV(无需保密,可随密文一起传输),不支持并行加密;

  • 适用场景:绝大多数业务场景(如接口数据加密、文件加密),是目前最主流的模式。

补充:除ECB/CBC外,AES还支持CTR、GCM等模式,其中GCM模式自带完整性校验,适合对安全性要求极高的场景。

五、JavaScript中实现AES加密与解密

前端场景中,AES加解密通常依赖crypto-js库(无原生AES API),以下是拆分后的实战代码及逐段讲解。

步骤1:安装CryptoJS库

首先需要安装前端加密常用的crypto-js库,该库封装了AES、MD5等主流加密算法:

npm install crypto-js

步骤2:AES-CBC模式实现(核心拆分讲解)

片段1:引入模块并定义基础参数

// 引入CryptoJS模块
const CryptoJS = require('crypto-js');

// 定义加密核心参数
let key = CryptoJS.enc.Utf8.parse('1234567890123456');
let iv = CryptoJS.enc.Utf8.parse('1234567890123456');
let text = '你好';

参数讲解

  • key(密钥):AES-128算法要求16位字符串,AES-256要求32位字符串;需通过CryptoJS.enc.Utf8.parse()转换为CryptoJS专用的WordArray格式,否则无法参与加解密运算。

  • iv(初始化向量):CBC模式必须指定,固定为16位字符串,作用是保证相同明文生成不同密文;同样需要转换为WordArray格式。

  • text(明文):需要加密的原始数据,支持任意字符串(如中文、数字、特殊字符)。

片段2:执行AES-CBC加密

// 执行CBC模式加密
let encryptResult = CryptoJS.AES.encrypt(text, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});

// 转换为Base64格式的密文
let cipherText = encryptResult.toString();
console.log('CBC模式加密结果(Base64):', cipherText);

加密逻辑讲解

  • CryptoJS.AES.encrypt()是核心加密方法,参数依次为「明文、密钥、配置对象」;

  • 配置对象中:mode指定加密模式为CBC,padding指定填充方式为PKCS7(AES标准填充方式,用于补足不足16字节的明文分组);

  • encrypt()返回的是CipherParams对象(包含密文、密钥等信息),需通过toString()转为Base64格式的密文(便于接口传输、存储)。

片段3:执行AES-CBC解密

// 执行CBC模式解密
let decryptResult = CryptoJS.AES.decrypt(cipherText, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});

// 转换为UTF-8格式的明文
let plainText = decryptResult.toString(CryptoJS.enc.Utf8);
console.log('CBC模式解密结果:', plainText); // 输出:你好

解密逻辑讲解

  • CryptoJS.AES.decrypt()是核心解密方法,参数与加密时完全一致(密文、密钥、配置对象);

  • 解密返回的结果默认是Hex格式的二进制数据,需通过toString(CryptoJS.enc.Utf8)转换为可读的UTF-8字符串;

  • 解密的核心要求:密钥、IV、模式、填充方式必须与加密时完全一致,否则会返回乱码或空值。

步骤3:AES-ECB模式实现(对比拆分讲解)

ECB模式无需IV,是最简单的AES模式,以下是拆分后的实现:

片段1:ECB模式加密

// ECB模式加密(无需IV)
let ecbEncryptResult = CryptoJS.AES.encrypt(text, key, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
});
let ecbCipherText = ecbEncryptResult.toString();
console.log('ECB模式加密结果:', ecbCipherText);

ECB加密讲解

  • ECB模式无需配置IV,只需指定模式和填充方式;

  • 由于缺少IV的「混淆」作用,相同明文会生成完全相同的密文,这是ECB模式的核心安全隐患。

片段2:ECB模式解密

// ECB模式解密
let ecbDecryptResult = CryptoJS.AES.decrypt(ecbCipherText, key, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
});
let ecbPlainText = ecbDecryptResult.toString(CryptoJS.enc.Utf8);
console.log('ECB模式解密结果:', ecbPlainText); // 输出:你好

ECB解密讲解

  • 解密参数仍需与加密一致,仅模式为ECB;

  • 实际开发中,除非特殊场景,否则禁止使用ECB模式处理敏感数据。

六、Python中实现AES加密与解密

Python中推荐使用pycryptodome库实现AES加解密(替代老旧的pycrypto),以下是拆分后的实战代码及逐段讲解,且与前端CryptoJS的结果完全互通。

步骤1:安装pycryptodome库

pip install pycryptodome

步骤2:AES-CBC模式实现(核心拆分讲解)

片段1:导入模块并定义基础参数

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64

# 定义加密核心参数
key = '1234567890123456'.encode('utf-8')
iv = '1234567890123456'.encode('utf-8')
text = '你好'.encode('utf-8')

参数讲解

  • 导入的模块作用:AES用于创建加解密实例,pad/unpad用于明文的补位/去补位,base64用于密文格式转换;

  • 所有参数需通过encode('utf-8')转为bytes格式(Python加密算法仅支持字节数据);

  • key和iv的长度、内容需与前端完全一致(16位字符串),否则前后端加解密无法互通。

片段2:执行AES-CBC加密

# 创建AES加密器实例(指定CBC模式)
aes_encrypt = AES.new(key, AES.MODE_CBC, iv)

# 明文补位:PKCS7填充(AES.block_size=16)
pad_text = pad(text, AES.block_size)

# 执行加密
encrypted_text = aes_encrypt.encrypt(pad_text)

# 转换为Base64格式(与前端格式统一)
encrypt_result = base64.b64encode(encrypted_text).decode('utf-8')
print('CBC模式加密结果(Base64):', encrypt_result)

加密逻辑讲解

  • AES.new()创建加密实例,参数为「密钥、模式、IV」,模式指定为AES.MODE_CBC

  • pad()补位:AES要求明文长度是16的倍数,pad()会按PKCS7规则自动补足不足的部分;

  • encrypt()执行加密,返回二进制密文;

  • base64.b64encode()将二进制密文转为Base64字符串(与前端CryptoJS的输出格式一致,便于跨语言传输)。

片段3:执行AES-CBC解密

# 创建AES解密器实例(参数与加密完全一致)
aes_decrypt = AES.new(key, AES.MODE_CBC, iv)

# 解密:先将Base64密文转回二进制
decrypted_text = aes_decrypt.decrypt(base64.b64decode(encrypt_result))

# 去掉补位:恢复原始明文长度
unpad_text = unpad(decrypted_text, AES.block_size)

# 转为UTF-8字符串
plain_text = unpad_text.decode('utf-8')
print('CBC模式解密结果:', plain_text)  # 输出:你好

解密逻辑讲解

  • 解密实例的参数必须与加密时完全一致(key、mode、iv),这是解密成功的核心;

  • base64.b64decode()将前端传入的Base64密文转回二进制,才能被decrypt()处理;

  • unpad()去掉加密时添加的补位,恢复原始明文的长度;

  • 最后通过decode('utf-8')将二进制明文转回可读的字符串。

步骤3:Python实现的关键注意事项

  1. 补位/去补位:Python的pycryptodome库需要手动调用pad()/unpad(),而前端CryptoJS会自动处理,这是跨语言实现的核心差异点;

  2. 数据格式:Python加密仅支持bytes类型,需注意字符串与字节的转换;

  3. 密文格式:前后端统一使用Base64格式,避免二进制数据传输时的编码问题;

  4. 密钥安全:key需严格保管(如后端存储在配置文件),IV可随密文一起传输(无需保密)。

七、总结

  1. 对称加密的核心是「单密钥加解密」,AES是当前主流算法,DES因安全性不足已淘汰;

  2. 工作模式中CBC是业务首选,ECB仅适合简单测试场景,需注意IV的配置和传输;

  3. 跨语言(JS/Python)AES互通的核心:密钥/IV长度一致、模式/填充方式一致、密文格式一致(Base64);

  4. 对称加密适合大量数据加密,但需结合非对称加密解决密钥传输的安全问题。

掌握AES加解密的原理和实战实现,能有效保障项目中敏感数据的安全,也是前端/后端开发者的核心基础能力之一。