常用加解密算法 - AES/CBC(一)

AES 加解密的核心原理

AES(Advanced Encryption Standard,高级加密标准),它是一种对称加密算法(加密和解密使用同一密钥),具有以下特点:

  • 分组加密
    将明文分成128位(16字节)的块,按块进行加密,支持密钥长度为128位、192位、256位(密钥越长安全性越高)。
  • 替代-置换网络
    通过字节替换、行移位、列混淆、轮密钥加等操作,对数据进行多层非线性变换,确保加密强度。
  • 高效性
    硬件和软件实现均高效,适用于各种设备和场景。

主要应用场景与实例

数据传输加密(网络通信)

  • 场景需求
    保护网络中传输的数据不被窃听或篡改。
  • 典型例子
    • HTTPS协议:网站通过TLS/SSL协议实现加密通信,其中AES是默认的对称加密算法(如AES-256-GCM),用于加密浏览器与服务器之间的网页内容、用于账户密码等数据。
    • VPN(虚拟专用网络):如OpenVPN、IPsec VPN中,AES用于加密远程访问的数据流,确保企业内部网络通信安全(例如:员工通过VPN访问公司服务器时的文件传输)。
    • 即时通讯软件:微信、WhatsApp的消息加密采用AES算法,对聊天内容、文件传输进行加密,防止中间人攻击。

存储数据加密(硬盘、云端)

  • 场景需求:保护存储在设备或云端的数据,即使存储介质丢失或被入侵,数据也无法被破解。
  • 典型例子
    • 硬盘加密:Windows BitLocker、macOS FileVault对硬盘进行全磁盘加密,核心算法采用AES(AES-256),加密用户的系统文件、个人数据(如文档、照片)。
    • 云存储服务:Dropbox、Good Drive在存储用户文件时,使用AES对文件进行加密(用户上传后先加密再存储,下载时解密),防止云端服务器被攻击导致数据泄露。
    • 移动设备加密:iPhone的Touch ID/Face ID解锁功能背后,AE用于加密手机存储的指纹、面容数据及用户隐私信息。

物联网(IoT)与嵌入式设备

  • 场景需求:物联网设备(如智能家电、传感器)的数据传输和本地存储需轻量化加密。
  • 典型例子:
    • 智能家居设备:小米智能门锁、华为智能摄像头与云端的通信使用AES加密,确保用户开销密码、监控视频不被截获。
    • 工业传感器:工厂中的传感器采集数据后,通过AES加密传输至中央控制系统,防止工业数据被恶意篡改(如能源行业的管道压力数据传输)。
    • RFID标签加密:部分高安全性RFID标签(如金融IC卡、电子护照)使用AES对用户身份信息加密,防止标签被伪造或信息窃取(身份证芯片内的个人信息保护)。

金融与支付系统

  • 场景需求:金融交易对安全性要求极高,需确保账户信息、交易数据的机密性。
  • 典型例子:
    • 银行卡交易:银联、Visa的POS机刷卡交易中,AES用于加密银行卡号、CVV码等敏感信息,防止刷卡时数据被侧录器窃取。
    • 电子钱包:支付宝、微信支付的资金转账数据,通过AES加密传输,同时本地存储的支付密码也以AES加密形式保存。
    • 区块链加密:部分区块链平台(如以太坊)在智能合约数据存储和传输中使用AES,保护用户账户余额、交易记录等信息。

AES加解密的技术优势与挑战

  • 优势
    • 安全性高:至今未被发现实质性的破解方法,是目前全球应用最广泛的对称加密标准。
    • 效率均衡:相对非对称加密(如RSA),AES加解密速度快,适合处理大量数据(如视频流、文件传输)。
  • 挑战
    • 密钥管理:对称加密的密钥需安全传输和存储(通常结合非对称加密传输密钥,如RSA),否则密钥泄露会导致数据全被破解。
    • 量子计算威胁:未来量子计算机可能对AES-256等算法构成潜在威胁(但目前尚未有实际破解案例),因此各国也在研发抗量子加密算法(如NIST的后量子密码标准)。

综合应用

实际场景中,AES常与其他算法配合使用,例如:

  • AES+HMAC:加密后用哈希消息消息认证码(如SHA-256)确保数据完整性和身份验证(如HTTPS中的数据传输)。
  • AES+RSA:用RSA非对称加密传输AES密钥,再用AES加密量数据(如电子邮件加密工具GPG的工具模式)。

Java中AES加解密示例

1
2
# example.txt
This is an AES encrypt/decrypt example file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

/**
* 文件加密工具(AES-256-CBC)
* 使用 AES-256-CBC 模式加密文件程序,包含文件读取、加密处理和写入操作
* 这个例子使用 CBC 模式(需要初始化向量 IV)和 PKCS5Padding 填充方式,适合加密大文件。
* 注意 IV 需要随密文一起存储或传输。
*/
public class FileEncryptor {

private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";

// 生成随机密钥
public static SecretKey generateKey(int keySize) throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
keyGenerator.init(keySize);
return keyGenerator.generateKey();
}

// 生成初始化向量
public static IvParameterSpec generateIv() {
byte[] iv = new byte[16];
SecureRandom secureRandom = new SecureRandom();
return new IvParameterSpec(iv);
}

// 加密文件
public static void encryptFile(SecretKey key, IvParameterSpec iv, File inputFile, File outputFile) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IOException {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);

try (FileInputStream fis = new FileInputStream(inputFile);
FileOutputStream fos = new FileOutputStream(outputFile);
CipherOutputStream cos = new CipherOutputStream(fos, cipher)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
cos.write(buffer, 0, bytesRead);
}
}
}

// 解密文件
public static void decryptFile(SecretKey key, IvParameterSpec iv, File inputFile, File outputFile) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, key, iv);

try (FileInputStream fis = new FileInputStream(inputFile);
CipherInputStream cis = new CipherInputStream(fis, cipher);
FileOutputStream fos = new FileOutputStream(outputFile)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = cis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
}

// 把密钥转换成字符串(用于存储或传输密钥)
public static String keyToString(SecretKey secretKey) {
return Base64.getEncoder().encodeToString(secretKey.getEncoded());
}

// 把字符串转换成密钥(用于后续加解密)
public static SecretKey stringToKey(String keyString) {
byte[] keyBytes = Base64.getDecoder().decode(keyString);
return new SecretKeySpec(keyBytes, ALGORITHM);
}

public static void main(String[] args) {
try {
// 生成密钥
SecretKey key = generateKey(256);

// 生成IV
IvParameterSpec iv = generateIv();

// 文件路径
File originalFile = new File("example.txt");
File encryptedFile = new File("example.encrypted");
File decryptedFile = new File("example.decrypted");

// 加密文件
encryptFile(key, iv, originalFile, encryptedFile);
System.out.println("文件加密完成");

// 解密文件
decryptFile(key, iv, encryptedFile, decryptedFile);
System.out.println("文件解密完成");

// 保存密钥
String keyString = keyToString(key);
System.out.println("密钥=" + keyString);

// 加载密钥
SecretKey loadKey = stringToKey(keyString);
System.out.println("密钥转换成功");
} catch (Exception e) {
e.printStackTrace();
}
}

}