Java中的对称加密算法的原理与实现

简介: 本文详细解析了Java中三种常用对称加密算法(AES、DES、3DES)的实现原理及应用。对称加密使用相同密钥进行加解密,适合数据安全传输与存储。AES作为现代标准,支持128/192/256位密钥,安全性高;DES采用56位密钥,现已不够安全;3DES通过三重加密增强安全性,但性能较低。文章提供了各算法的具体Java代码示例,便于快速上手实现加密解密操作,帮助用户根据需求选择合适的加密方案保护数据安全。

一、引言

对称加密算法,也称为密钥加密算法,是加密和解密使用相同密钥的一类加密算法。在Java中,这些算法常用于数据的安全传输和存储。本文将为您详细解析三种常用对称加密算法的实现原理,并给出具体的Java代码示例。

二、AES (高级加密标准)

AES,全称为Advanced Encryption Standard,是美国联邦政府采用的一种区块加密标准。它采用分组加密的方式,对每个数据块进行独立加密。AES提供了128位、192位和256位三种密钥长度,分别使用128位、192位和256位密钥进行数据加密。 ::: block-1

  1. 选择一个密钥:AES算法需要一个密钥,这个密钥可以是128位、192位或256位长。密钥的长度决定了AES加密的安全性。
  2. 选择一个模式:AES可以与多种模式一起使用,例如ECB(电子密码本)模式、CBC(密码块链)模式、CFB(密码反馈)模式、OFB(输出反馈)模式和CTR(计数器)模式。这些模式定义了如何使用AES算法来加密数据。
  3. 初始化向量(可选):在某些模式中,如CBC和CTR,需要一个初始化向量。初始化向量是随机的,用于增强安全性。
  4. 加密过程
  • 加密器实例化:首先,你需要使用Java的Cipher类创建一个AES加密器实例。例如,要创建一个使用AES/CBC/PKCS5Padding模式的加密器,你可以使用以下代码:

ini

  1. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  • 设置密钥和初始化向量:接下来,你需要设置密钥和初始化向量。如果你要使用CBC模式,你需要同时设置这两个值。对于其他模式,只需要设置密钥。
  1. csharp
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec); 其中secretKey是你要使用的密钥,ivParameterSpec是一个IvParameterSpec对象,用于指定初始化向量。
  • 加密数据:最后,你可以使用加密器来加密数据。例如:
  1. ini
    byte[] encrypted = cipher.doFinal(plainText); 其中plainText是要加密的原始数据,encrypted是加密后的数据。
  2. 解密过程:解密过程与加密过程类似,但方向相反。以下是解密过程的步骤:
  • 解密器实例化:同样,你需要使用Java的Cipher类创建一个AES解密器实例。例如:
  1. ini
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  • 设置密钥和初始化向量:解密时也需要设置密钥和初始化向量。与加密相同,如果你要使用CBC模式,你需要同时设置这两个值。对于其他模式,只需要设置密钥。
  1. csharp
    cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
  • 解密数据:最后,你可以使用解密器来解密数据。例如:
  1. ini
    byte[] decrypted = cipher.doFinal(encrypted); 其中encrypted是要解密的加密数据,decrypted是解密后的原始数据。

::: Java实现示例:

java

import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class AESExample { public static String encrypt(String plainText, String key) throws Exception { SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] encryptedBytes = cipher.doFinal(plainText.getBytes()); return Base64.getEncoder().encodeToString(encryptedBytes); } public static String decrypt(String encryptedText, String key) throws Exception { SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] originalBytes = Base64.getDecoder().decode(encryptedText); byte[] decryptedBytes = cipher.doFinal(originalBytes); return new String(decryptedBytes); } }

在实际应用中,你需要确保密钥的安全性,防止它被泄露。此外,你应该使用安全的随机数生成器来生成初始化向量。最后,你应该定期更新密钥,以防止密钥被破解。

三、DES (数据加密标准)

DES,全称为Data Encryption Standard,是最早的国际加密标准。它使用56位密钥和64位明文块进行加密,产生64位密文块。值得注意的是,DES的安全性在现代计算机科学中已经不再被认为足够安全。这是因为现代计算机可以并行处理大量数据,从而在合理的时间内暴力破解DES加密。因此,对于需要高安全性的应用,更推荐使用更安全的加密算法,如AES。 ::: block-1

  1. 密钥生成:DES使用一个64位的密钥来加密和解密数据。但是,实际使用的密钥长度只有56位,因为8位用于奇偶校验。
  2. 初始置换:输入的64位数据块首先经过一个初始置换函数,将数据重新排列。
  3. 16轮迭代:接下来,数据会经过16轮的迭代,每一轮都使用一个特定的函数进行操作。每一轮都涉及到替换(Substitution)、行位移(Permutation)和模2^32乘法(乘法)。
  4. 逆初始置换:经过16轮迭代后,数据会经过一个逆初始置换函数,将数据重新排列回原来的顺序。
  5. 输出:最后,输出的64位数据就是加密后的结果。

解密的过程与加密过程类似,只是每一轮的函数顺序相反。首先进行逆初始置换,然后进行16轮迭代(但每一轮的函数顺序与加密时相反),最后进行初始置换。 ::: Java实现示例:

java

import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; public class DESExample { public static void main(String[] args) throws Exception { String key = "abcdefgh"; // DES密钥必须为8字节长 String plaintext = "Hello, World!"; //加密 String encrypted = encrypt(key, plaintext); System.out.println("Encrypted: " + encrypted); //解密 String decrypted = decrypt(key, encrypted); System.out.println("Decrypted: " + decrypted); } public static String encrypt(String key, String plaintext) throws Exception { DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8)); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey securekey = keyFactory.generateSecret(desKeySpec); Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, securekey); byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(encryptedBytes); } public static String decrypt(String key, String ciphertext) throws Exception { DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8)); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey securekey = keyFactory.generateSecret(desKeySpec); Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, securekey); byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(ciphertext)); return new String(decryptedBytes, StandardCharsets.UTF_8); } }

四、3DES (三重数据加密算法)

3DES是对DES的一种扩展,通过使用三个DES加密算法来增加安全性。它使用三个密钥进行三次加密,从而提供更高的安全性。然而,由于计算开销较大,3DES在现代应用中并不常用。 ::: block-1

  1. 密钥生成:3DES使用一个密钥作为输入,生成三个密钥,分别为K1、K2和K3。这三个密钥都用于加密和解密过程。
  2. 加密过程:明文被分为长度为64位的块,然后通过三个密钥进行三次加密。第一次使用K1加密,第二次使用K2解密(实际上是使用了与第一次相反的密钥),第三次使用K3加密。
  3. 解密过程:解密过程与加密过程相反。首先使用K3解密,然后使用K2加密,最后使用K1解密。

具体地,一个64位的块被分为两个32位的子块,每个子块都单独加密。每个密钥都用于一个电子密码本(ECB)模式下的DES加密。因此,每个块都独立地加密和解密。 ::: Java实现示例:

java

import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; public class DESedeExample { public static void main(String[] args) throws Exception { String key = "ac1rm9cpac1rm9cpac1rm9cp"; // 3DES密钥必须为24字节长 String plaintext = "Hello, World!"; //加密 String cipherText = encrypt(key, plaintext); System.out.println("cipherText: " + cipherText); //解密 String decryptedText = decrypt(key, cipherText); System.out.println("DecryptedText: " + decryptedText); } public static String encrypt(String key, String plaintext) throws Exception { DESedeKeySpec des3KeySpec = new DESedeKeySpec(key.getBytes(StandardCharsets.UTF_8)); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); SecretKey securekey = keyFactory.generateSecret(des3KeySpec); Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, securekey); byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(encryptedBytes); } public static String decrypt(String key, String ciphertext) throws Exception { DESedeKeySpec des3KeySpec = new DESedeKeySpec(key.getBytes(StandardCharsets.UTF_8)); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); SecretKey securekey = keyFactory.generateSecret(des3KeySpec); Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, securekey); byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(ciphertext)); return new String(decryptedBytes, StandardCharsets.UTF_8); } }

五、总结

本文详细介绍了Java中常用的三种对称加密算法:AES、DES、3DES的实现原理。通过了解这些算法的原理和特点,您可以在实际应用中选择合适的加密算法来保护您的数据安全。同时提供了具体的Java代码示例,帮助您快速实现这些算法的加密和解密操作。


转载来源:https://juejin.cn/post/7317252368546955304

相关文章
|
16天前
|
缓存 负载均衡 算法
负载均衡相关问题详细分享一下
负载均衡相关问题详细分享
159 67
|
5天前
|
算法 网络协议 Java
Spring Boot 的接口限流算法
本文介绍了高并发系统中流量控制的重要性及常见的限流算法。首先讲解了简单的计数器法,其通过设置时间窗口内的请求数限制来控制流量,但存在临界问题。接着介绍了滑动窗口算法,通过将时间窗口划分为多个格子,提高了统计精度并缓解了临界问题。随后详细描述了漏桶算法和令牌桶算法,前者以固定速率处理请求,后者允许一定程度的流量突发,更符合实际需求。最后对比了各算法的特点与适用场景,指出选择合适的算法需根据具体情况进行分析。
104 56
Spring Boot 的接口限流算法
|
18天前
|
SQL JSON API
什么!我把SQL编辑器装进了大模型?
本文旨在通过约束解码技术,赋予大型语言模型在生成SQL等结构化内容时更高的准确性、可控性与可解释性,从而满足企业级场景对“精准生成”的严苛要求。
381 125
什么!我把SQL编辑器装进了大模型?
|
19天前
|
人工智能 前端开发 JavaScript
SpringBoot实现网页消息推送的5种方法
本文详细介绍了在SpringBoot中实现网页消息推送的几种主流方案,包括短轮询、长轮询、SSE(Server-Sent Events)、WebSocket以及STOMP。每种方案各有优缺点,适用于不同的场景需求。短轮询简单易实现但效率低;长轮询提升了实时性但仍有限制;SSE适合单向通信且轻量高效;WebSocket支持全双工通信,适合高实时性要求的场景;STOMP基于WebSocket,提供更高级的消息传递功能。通过对比分析,开发者可根据业务需求、性能要求及浏览器兼容性选择最适合的技术方案,同时可结合多种技术实现优雅降级,优化用户体验。
244 57
|
7月前
|
监控 Java 编译器
Java虚拟机调优指南####
本文深入探讨了Java虚拟机(JVM)调优的精髓,从内存管理、垃圾回收到性能监控等多个维度出发,为开发者提供了一系列实用的调优策略。通过优化配置与参数调整,旨在帮助读者提升Java应用的运行效率和稳定性,确保其在高并发、大数据量场景下依然能够保持高效运作。 ####
180 58
|
11月前
|
前端开发 对象存储
oss的断点续传在react中的应用
使用阿里云OSS的`multipartUpload`可自动管理文件切片与断点续传吗?测试时,上传一半中断(如刷新页面或重启浏览器),再续应从断点处继续。
210 67
|
消息中间件 存储 网络协议
MQTT-轻量级的物联网消息传输协议
随着 5G 时代的来临,万物互联的伟大构想正在成为现实。联网的 物联网设备 在 2018 年已经达到了 70 亿,在未来两年,仅智能水电气表就将超过10亿。
569 57