GCM即Galois/Counter Mode,指的是加密采用Counter模式,并且带有GMAC消息认证码
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
/**
* Description: GCM即Galois/Counter Mode,指的是加密采用Counter模式,并且带有GMAC消息认证码
*
* @author whip
* @version 1.0
* @date 2023/11/28 10:06
*/
@Slf4j
public class AesGcmUtil {
/**
* 加密
*
* @param plaintext
* @param secretString
* @return
* @throws Exception
*/
public String encrypt(String plaintext, String secretString) throws Exception {
byte[] IV = new byte[12];
SecureRandom random = new SecureRandom();
random.nextBytes(IV);
byte[] secretKey = Base64.getDecoder().decode(secretString);
SecretKeySpec keySpec = new SecretKeySpec(secretKey, "AES");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, IV);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
byte[] cipherText = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
ByteBuffer byteBuffer = ByteBuffer.allocate(IV.length + cipherText.length);
byteBuffer.put(IV);
byteBuffer.put(cipherText);
return Base64.getEncoder().encodeToString(byteBuffer.array());
}
/**
* 解密
*
* @param ciphertext
* @param secretString
* @return
* @throws Exception
*/
public String decrypt(String ciphertext, String secretString) throws Exception {
byte[] encrypted = Base64.getDecoder().decode(ciphertext);
byte[] IV = Arrays.copyOfRange(encrypted, 0, 12);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, IV);
byte[] secretKey = Base64.getDecoder().decode(secretString);
SecretKeySpec keySpec = new SecretKeySpec(secretKey, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
byte[] plaintext = cipher.doFinal(Arrays.copyOfRange(encrypted, 12, encrypted.length));
return new String(plaintext);
}
/**
* 产生密钥工具方法
*
* @throws Exception
*/
public String generateSecret() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);
SecretKey key = keyGenerator.generateKey();
byte[] bytes = key.getEncoded();
log.info("生成密钥:{}", Base64.getEncoder().encodeToString(bytes));
return Base64.getEncoder().encodeToString(bytes);
}
public static void main(String[] args) throws Exception {
AesGcmUtil util = new AesGcmUtil();
// 产生密钥
String secret = util.generateSecret();
// 加密
String ciphertext = util.encrypt("XXX-测试", secret);
log.info("加密结果:{}", ciphertext);
// 解密
String decrypt = util.decrypt(ciphertext, secret);
log.info("解密结果: {}", decrypt);
}
}