import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;
import java.util.Base64;
public class AESUtil {
private static final String AES = "AES";
public static String encrypt(String plaintext, byte[] key, String mode) throws Exception {
Cipher cipher = Cipher.getInstance(AES + "/" + mode + "/PKCS5Padding");
SecretKey secretKey = new SecretKeySpec(key, AES);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encrypted = cipher.doFinal(plaintext.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
public static String decrypt(String encryptedText, byte[] key, String mode) throws Exception {
Cipher cipher = Cipher.getInstance(AES + "/" + mode + "/PKCS5Padding");
SecretKey secretKey = new SecretKeySpec(key, AES);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] original = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(original);
}
public static void main(String[] args) throws Exception {
// Generate a random key
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
keyGenerator.init(256); // AES-256
SecretKey secretKey = keyGenerator.generateKey();
byte[] key = secretKey.getEncoded();
// Example usage
String data = "Hello World";
String encryptedECB = encrypt(data, key, "ECB");
String decryptedECB = decrypt(encryptedECB, key, "ECB");
String encryptedCTR = encrypt(data, key, "CTR");
// For CTR, you need to provide an IV
byte[] iv = new byte[16]; // 128-bit IV for AES
new SecureRandom().nextBytes(iv);
System.out.println("IV for CTR: " + Base64.getEncoder().encodeToString(iv));
// For GCM, you need to provide an IV and specify the tag length
byte[] ivGCM = new byte[12]; // 96-bit IV for GCM
new SecureRandom().nextBytes(ivGCM);
GCMParameterSpec gcmParamSpec = new GCMParameterSpec(128, ivGCM);
Cipher gcmCipher = Cipher.getInstance("AES/GCM/NoPadding");
gcmCipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmParamSpec);
byte[] encryptedGCM = gcmCipher.doFinal(data.getBytes());
byte[] tag = gcmCipher.getIV(); // The tag is the IV used in GCM mode
String encryptedGCMBase64 = Base64.getEncoder().encodeToString(encryptedGCM);
System.out.println("Encrypted (GCM): " + encryptedGCMBase64);
System.out.println("Tag (GCM): " + Base64.getEncoder().encodeToString(tag));
}
}
- 定义了一个`encrypt`和`decrypt`方法,它们接受模式作为参数。
- 对于CTR和GCM模式,需要提供一个初始化向量(IV)。使用`SecureRandom`生成了一个随机的IV。
- 对于GCM模式,还需要指定认证标签的长度,通常是128位。
- 加密和解密方法使用了`PKCS5Padding`填充方式,这在ECB和CTR模式中是合适的。然而,GCM模式通常使用`NoPadding`,因为GCM本身提供了认证机制,不需要填充。
-使用了`Base64`编码来处理加密后的字节数据,使其可以作为字符串打印或存储。
Java实现AES加解密时,Mode动态支持ECB,CTR,GCM
最新推荐文章于 2024-08-21 14:08:25 发布