一、引言
对称加密算法,也称为密钥加密算法,是加密和解密使用相同密钥的一类加密算法。在Java中,这些算法常用于数据的安全传输和存储。本文将为您详细解析三种常用对称加密算法的实现原理,并给出具体的Java代码示例。
二、AES (高级加密标准)
AES,全称为Advanced Encryption Standard,是美国联邦政府采用的一种区块加密标准。它采用分组加密的方式,对每个数据块进行独立加密。AES提供了128位、192位和256位三种密钥长度,分别使用128位、192位和256位密钥进行数据加密。 ::: block-1
- 选择一个密钥:AES算法需要一个密钥,这个密钥可以是128位、192位或256位长。密钥的长度决定了AES加密的安全性。
- 选择一个模式:AES可以与多种模式一起使用,例如ECB(电子密码本)模式、CBC(密码块链)模式、CFB(密码反馈)模式、OFB(输出反馈)模式和CTR(计数器)模式。这些模式定义了如何使用AES算法来加密数据。
- 初始化向量(可选):在某些模式中,如CBC和CTR,需要一个初始化向量。初始化向量是随机的,用于增强安全性。
- 加密过程:
- 加密器实例化:首先,你需要使用Java的
Cipher
类创建一个AES加密器实例。例如,要创建一个使用AES/CBC/PKCS5Padding模式的加密器,你可以使用以下代码:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- 设置密钥和初始化向量:接下来,你需要设置密钥和初始化向量。如果你要使用CBC模式,你需要同时设置这两个值。对于其他模式,只需要设置密钥。
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
其中secretKey
是你要使用的密钥,ivParameterSpec
是一个IvParameterSpec
对象,用于指定初始化向量。
- 加密数据:最后,你可以使用加密器来加密数据。例如:
byte[] encrypted = cipher.doFinal(plainText);
其中plainText
是要加密的原始数据,encrypted
是加密后的数据。
- 解密过程:解密过程与加密过程类似,但方向相反。以下是解密过程的步骤:
- 解密器实例化:同样,你需要使用Java的
Cipher
类创建一个AES解密器实例。例如:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- 设置密钥和初始化向量:解密时也需要设置密钥和初始化向量。与加密相同,如果你要使用CBC模式,你需要同时设置这两个值。对于其他模式,只需要设置密钥。
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
- 解密数据:最后,你可以使用解密器来解密数据。例如:
byte[] decrypted = cipher.doFinal(encrypted);
其中encrypted
是要解密的加密数据,decrypted
是解密后的原始数据。
::: 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
- 密钥生成:DES使用一个64位的密钥来加密和解密数据。但是,实际使用的密钥长度只有56位,因为8位用于奇偶校验。
- 初始置换:输入的64位数据块首先经过一个初始置换函数,将数据重新排列。
- 16轮迭代:接下来,数据会经过16轮的迭代,每一轮都使用一个特定的函数进行操作。每一轮都涉及到替换(Substitution)、行位移(Permutation)和模2^32乘法(乘法)。
- 逆初始置换:经过16轮迭代后,数据会经过一个逆初始置换函数,将数据重新排列回原来的顺序。
- 输出:最后,输出的64位数据就是加密后的结果。
解密的过程与加密过程类似,只是每一轮的函数顺序相反。首先进行逆初始置换,然后进行16轮迭代(但每一轮的函数顺序与加密时相反),最后进行初始置换。 ::: 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
- 密钥生成:3DES使用一个密钥作为输入,生成三个密钥,分别为K1、K2和K3。这三个密钥都用于加密和解密过程。
- 加密过程:明文被分为长度为64位的块,然后通过三个密钥进行三次加密。第一次使用K1加密,第二次使用K2解密(实际上是使用了与第一次相反的密钥),第三次使用K3加密。
- 解密过程:解密过程与加密过程相反。首先使用K3解密,然后使用K2加密,最后使用K1解密。
具体地,一个64位的块被分为两个32位的子块,每个子块都单独加密。每个密钥都用于一个电子密码本(ECB)模式下的DES加密。因此,每个块都独立地加密和解密。 ::: 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代码示例,帮助您快速实现这些算法的加密和解密操作。