【对称加密】DES与AES算法详解及Java实现

【对称加密】DES与AES算法详解及Java实现

对称加密:DES与AES算法详解及Java实现

目录

对称加密概述

DES算法详解

AES算法详解

Java实现示例

安全注意事项

总结

1. 对称加密概述

对称加密是指加密和解密使用相同密钥的加密算法。主要特点包括:

高效性:比非对称加密快100-1000倍

密钥管理:需要安全地共享密钥

常见算法:DES、3DES、AES、Blowfish等

应用场景:大数据量加密、SSL/TLS会话密钥、磁盘加密等

基本流程:

明文 + 密钥 → 加密算法 → 密文

密文 + 密钥 → 解密算法 → 明文

2. DES算法详解

基本概念

Data Encryption Standard (数据加密标准)

1977年被NIST采纳为联邦标准

分组长度:64位

密钥长度:56位(实际64位,含8位奇偶校验)

已被认为不够安全(1999年被暴力破解)

核心原理

初始置换(IP):打乱64位明文的顺序

16轮Feistel网络:

将数据分为左右两半(各32位)

右半通过扩展置换(32→48位)

与子密钥异或

通过S盒替换(48→32位)

与左半异或并交换左右

最终置换(FP):IP的逆置换

密钥生成

从64位密钥中去掉8位校验位

通过置换选择PC-1得到56位密钥

每轮左移1-2位生成16个子密钥

安全性问题:

56位密钥太小(2⁵⁶种可能)

存在弱密钥和半弱密钥

已被AES取代

3. AES算法详解

基本概念

Advanced Encryption Standard (高级加密标准)

2001年取代DES成为新标准

分组长度:128位

密钥长度:128/192/256位

目前最安全的对称加密算法

核心原理(Rijndael算法)

字节替换(SubBytes):使用S盒进行非线性替换

行移位(ShiftRows):每行循环左移不同位数

列混淆(MixColumns):矩阵乘法混淆数据

轮密钥加(AddRoundKey):与子密钥异或

加密轮数:

128位密钥:10轮

192位密钥:12轮

256位密钥:14轮

密钥扩展

将初始密钥扩展为(轮数+1)×128位的轮密钥

使用Rcon常量和S盒进行非线性变换

优势:

更强的安全性(最小128位密钥)

更高的效率(适合硬件实现)

无已知的有效攻击方式

4. Java实现示例

DES加密解密示例

import javax.crypto.*;

import javax.crypto.spec.DESKeySpec;

import java.security.spec.KeySpec;

public class DESExample {

public static void main(String[] args) throws Exception {

String plainText = "Hello, DES!";

String secretKey = "MySecretKey"; // 至少8字节

// 密钥生成

KeySpec keySpec = new DESKeySpec(secretKey.getBytes());

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");

SecretKey key = keyFactory.generateSecret(keySpec);

// 加密

Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");

cipher.init(Cipher.ENCRYPT_MODE, key);

byte[] encrypted = cipher.doFinal(plainText.getBytes());

System.out.println("Encrypted: " + bytesToHex(encrypted));

// 解密

cipher.init(Cipher.DECRYPT_MODE, key);

byte[] decrypted = cipher.doFinal(encrypted);

System.out.println("Decrypted: " + new String(decrypted));

}

private static String bytesToHex(byte[] bytes) {

StringBuilder sb = new StringBuilder();

for (byte b : bytes) {

sb.append(String.format("%02X", b));

}

return sb.toString();

}

}

AES加密解密示例

import javax.crypto.*;

import javax.crypto.spec.SecretKeySpec;

import java.security.SecureRandom;

import java.util.Base64;

public class AESExample {

public static void main(String[] args) throws Exception {

String plainText = "Hello, AES!";

String secretKey = "MySuperSecretKey123"; // 16/24/32字节

// 确保密钥长度正确

byte[] keyBytes = new byte[16]; // 128位

System.arraycopy(secretKey.getBytes(), 0, keyBytes, 0, Math.min(secretKey.length(), keyBytes.length));

SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");

// 加密

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

cipher.init(Cipher.ENCRYPT_MODE, key);

byte[] encrypted = cipher.doFinal(plainText.getBytes());

System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encrypted));

// 解密

cipher.init(Cipher.DECRYPT_MODE, key);

byte[] decrypted = cipher.doFinal(encrypted);

System.out.println("Decrypted: " + new String(decrypted));

}

}

更安全的AES-CBC模式示例

import javax.crypto.*;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import java.security.SecureRandom;

import java.util.Base64;

public class AESCBCExample {

public static void main(String[] args) throws Exception {

String plainText = "Hello, AES CBC Mode!";

String secretKey = "ThisIsA128BitKey!!"; // 16字节

// 生成随机IV(初始化向量)

byte[] iv = new byte[16];

new SecureRandom().nextBytes(iv);

IvParameterSpec ivSpec = new IvParameterSpec(iv);

SecretKeySpec key = new SecretKeySpec(secretKey.getBytes(), "AES");

// 加密

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);

byte[] encrypted = cipher.doFinal(plainText.getBytes());

// 组合IV和密文(IV不需要保密)

byte[] combined = new byte[iv.length + encrypted.length];

System.arraycopy(iv, 0, combined, 0, iv.length);

System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);

System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(combined));

// 解密

byte[] extractedIv = new byte[16];

byte[] extractedCipherText = new byte[combined.length - 16];

System.arraycopy(combined, 0, extractedIv, 0, 16);

System.arraycopy(combined, 16, extractedCipherText, 0, extractedCipherText.length);

cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(extractedIv));

byte[] decrypted = cipher.doFinal(extractedCipherText);

System.out.println("Decrypted: " + new String(decrypted));

}

}

5. 安全注意事项

密钥管理

密钥生成:使用SecureRandom生成随机密钥

密钥存储:使用密钥管理系统或硬件安全模块(HSM)

密钥轮换:定期更换密钥

算法选择建议

优先使用AES:至少128位,推荐256位

避免使用DES:除非遗留系统要求

模式选择:

CBC模式(需要随机IV)

GCM模式(同时提供加密和认证)

避免ECB模式(相同明文产生相同密文)

其他安全实践

始终使用完整的初始化向量(IV)

对密文进行完整性验证(如HMAC)

使用适当的填充方案(PKCS#5/PKCS#7)

处理BadPaddingException时不泄露具体错误信息

6. 总结

对比DES和AES

特性

DES

AES

密钥长度

56位

128/192/256位

分组大小

64位

128位

安全性

已不安全

目前安全

性能

较慢

更快

轮数

16轮

10/12/14轮

选择建议

新系统:始终使用AES(至少128位)

遗留系统:考虑3DES过渡到AES

高安全性需求:使用AES-256 + GCM模式

最佳实践

结合对称和非对称加密(如RSA加密AES密钥)

使用标准库而非自己实现加密算法

定期评估加密方案的安全性

通过合理选择和实现对称加密算法,可以有效保护数据机密性。记住加密只是安全体系的一部分,需要结合认证、访问控制等其他措施构建完整的安全解决方案。

相关推荐

比赛策略的高级足球分析
365登录平台

比赛策略的高级足球分析

⌛ 08-11 👁️ 5904
西甲VS意甲,谁的欧冠底子更硬?
365登录平台

西甲VS意甲,谁的欧冠底子更硬?

⌛ 11-20 👁️ 5718