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

笔记哥 / 05-30 / 13点赞 / 0评论 / 258阅读
# 对称加密:DES与AES算法详解及Java实现 ## 目录 1. 对称加密概述 2. DES算法详解 3. AES算法详解 4. Java实现示例 5. 安全注意事项 6. 总结 * * * ## 1. 对称加密概述 对称加密是指加密和解密使用相同密钥的加密算法。主要特点包括: - **高效性**:比非对称加密快100-1000倍 - **密钥管理**:需要安全地共享密钥 - **常见算法**:DES、3DES、AES、Blowfish等 - **应用场景**:大数据量加密、SSL/TLS会话密钥、磁盘加密等 **基本流程**: ```csharp 明文 + 密钥 → 加密算法 → 密文 密文 + 密钥 → 解密算法 → 明文 ``` * * * ## 2. DES算法详解 ### 基本概念 - **Data Encryption Standard** (数据加密标准) - 1977年被NIST采纳为联邦标准 - 分组长度:64位 - 密钥长度:56位(实际64位,含8位奇偶校验) - 已被认为不够安全(1999年被暴力破解) ### 核心原理 1. **初始置换(IP)**:打乱64位明文的顺序 2. **16轮Feistel网络**: - 将数据分为左右两半(各32位) - 右半通过扩展置换(32→48位) - 与子密钥异或 - 通过S盒替换(48→32位) - 与左半异或并交换左右 3. **最终置换(FP)**:IP的逆置换 ### 密钥生成 1. 从64位密钥中去掉8位校验位 2. 通过置换选择PC-1得到56位密钥 3. 每轮左移1-2位生成16个子密钥 **安全性问题**: - 56位密钥太小(2⁵⁶种可能) - 存在弱密钥和半弱密钥 - 已被AES取代 * * * ## 3. AES算法详解 ### 基本概念 - **Advanced Encryption Standard** (高级加密标准) - 2001年取代DES成为新标准 - 分组长度:128位 - 密钥长度:128/192/256位 - 目前最安全的对称加密算法 ### 核心原理(Rijndael算法) 1. **字节替换(SubBytes)**:使用S盒进行非线性替换 2. **行移位(ShiftRows)**:每行循环左移不同位数 3. **列混淆(MixColumns)**:矩阵乘法混淆数据 4. **轮密钥加(AddRoundKey)**:与子密钥异或 **加密轮数**: - 128位密钥:10轮 - 192位密钥:12轮 - 256位密钥:14轮 ### 密钥扩展 - 将初始密钥扩展为(轮数+1)×128位的轮密钥 - 使用Rcon常量和S盒进行非线性变换 **优势**: - 更强的安全性(最小128位密钥) - 更高的效率(适合硬件实现) - 无已知的有效攻击方式 * * * ## 4. Java实现示例 ### DES加密解密示例 ```java 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加密解密示例 ```java 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模式示例 ```java 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. 安全注意事项 ### 密钥管理 1. **密钥生成**:使用`SecureRandom`生成随机密钥 2. **密钥存储**:使用密钥管理系统或硬件安全模块(HSM) 3. **密钥轮换**:定期更换密钥 ### 算法选择建议 - **优先使用AES**:至少128位,推荐256位 - **避免使用DES**:除非遗留系统要求 - **模式选择**: - CBC模式(需要随机IV) - GCM模式(同时提供加密和认证) - 避免ECB模式(相同明文产生相同密文) ### 其他安全实践 1. 始终使用完整的初始化向量(IV) 2. 对密文进行完整性验证(如HMAC) 3. 使用适当的填充方案(PKCS#5/PKCS#7) 4. 处理`BadPaddingException`时不泄露具体错误信息 * * * ## 6. 总结 ### 对比DES和AES | 特性 | DES | AES | | --- | --- | --- | | 密钥长度 | 56位 | 128/192/256位 | | 分组大小 | 64位 | 128位 | | 安全性 | 已不安全 | 目前安全 | | 性能 | 较慢 | 更快 | | 轮数 | 16轮 | 10/12/14轮 | ### 选择建议 1. **新系统**:始终使用AES(至少128位) 2. **遗留系统**:考虑3DES过渡到AES 3. **高安全性需求**:使用AES-256 + GCM模式 ### 最佳实践 - 结合对称和非对称加密(如RSA加密AES密钥) - 使用标准库而非自己实现加密算法 - 定期评估加密方案的安全性 通过合理选择和实现对称加密算法,可以有效保护数据机密性。记住加密只是安全体系的一部分,需要结合认证、访问控制等其他措施构建完整的安全解决方案。