AES GCM算法实现
当前业界敏感信息加密使用AES较多,GCM模式兼具效率和安全性,故选择使用该模式。
注意
我们经常使用256位秘钥,因为美国的安全管控,jdk8的较老版本安全策略不支持256位秘钥,需替换jdk\jre\lib\security 下的安全策略文件local_policy.jar 和US_export_policy.jar
java 1.8.0_151到1.8.0_161版本已经包含了不同的安全策略,需要修改jdk\jre\lib\security\java.security 文件,放开crypto.policy=unlimited的限制即可,这个配置决定选择policy目录下的unlimited或limited的策略文件;
java 1.8.0_162版本后默认crypto.policy=unlimited 则不需修改。
代码实现
package com.kwin.demo.api.util;import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;/*** @author kwin* @Date 2022/7/13 16:20**/
public class AESUtil {private static final String KEY_ALGORITHM = "AES";private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";private static final int TAG_LENGTH_BIT = 128;private static final int IV_LENGTH_BYTE = 12;private static final int SALT_LENGTH_BYTE = 16;private static final int AES_KEY_BIT = 256;/*** 安全随机数生成* @param numBytes* @return*/public static byte[] getRandomNonce(int numBytes) {byte[] nonce = new byte[numBytes];new SecureRandom().nextBytes(nonce);return nonce;}/*** 生成盐值* @return*/public static String generateSalt() {byte[] salt = getRandomNonce(SALT_LENGTH_BYTE);return Base64.encodeBase64String(salt);}/*** 生成初始向量* @return*/public static String generateIv() {byte[] iv = getRandomNonce(IV_LENGTH_BYTE);return Base64.encodeBase64String(iv);}/*** 生成256位秘钥* @return* @throws NoSuchAlgorithmException*/public static SecretKey getAESKey() throws NoSuchAlgorithmException {KeyGenerator keyGen = KeyGenerator.getInstance(KEY_ALGORITHM);keyGen.init(AES_KEY_BIT, SecureRandom.getInstanceStrong());return keyGen.generateKey();}/*** 生成256位秘钥,base64编码* @return* @throws NoSuchAlgorithmException*/public static String generateAESKey() throws NoSuchAlgorithmException {return Base64.encodeBase64String(getAESKey().getEncoded());}/*** 通过密码和盐值生成256位aes秘钥* @param password 密码* @param salt 盐值* @return* @throws NoSuchAlgorithmException* @throws InvalidKeySpecException*/public static SecretKey getAESKeyFromPassword(char[] password, byte[] salt)throws NoSuchAlgorithmException, InvalidKeySpecException {SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");// iterationCount = 65536KeySpec spec = new PBEKeySpec(password, salt, 65536, AES_KEY_BIT);SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), KEY_ALGORITHM);return secret;}/*** 加密* @param source 明文* @param secret 秘钥* @param iv 初始向量* @return* @throws Exception*/public static byte[] encrypt(byte[] source, SecretKey secret, byte[] iv) throws Exception {Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, secret, new GCMParameterSpec(TAG_LENGTH_BIT, iv));byte[] encryptedText = cipher.doFinal(source);return encryptedText;}/*** 加密,base64编码* @param source 明文* @param key 秘钥* @param iv 初始向量* @return* @throws Exception*/public static String encrypt(String source, String key, String iv) throws Exception {SecretKey secretKey = new SecretKeySpec(Base64.decodeBase64(key), KEY_ALGORITHM);//getAESKeyFromPassword(password.toCharArray(), Base64.decodeBase64(salt));byte[] encryptedText = encrypt(source.getBytes(StandardCharsets.UTF_8), secretKey, Base64.decodeBase64(iv));return Base64.encodeBase64String(encryptedText);}/*** 加密,通过base64编码,秘钥通过password和盐值生成* @param source 明文* @param password 密码* @param iv 初始向量* @param salt 盐值* @return* @throws Exception*/public static String encrypt(String source, String password, String iv, String salt) throws Exception {SecretKey secretKey = getAESKeyFromPassword(password.toCharArray(), Base64.decodeBase64(salt));byte[] encryptedText = encrypt(source.getBytes(StandardCharsets.UTF_8), secretKey, Base64.decodeBase64(iv));return Base64.encodeBase64String(encryptedText);}/*** 解密* @param encryptBytes 加密数组* @param secret 秘钥* @param iv 初始向量* @return* @throws Exception*/public static String decrypt(byte[] encryptBytes, SecretKey secret, byte[] iv) throws Exception {Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, secret, new GCMParameterSpec(TAG_LENGTH_BIT, iv));byte[] plainText = cipher.doFinal(encryptBytes);return new String(plainText, StandardCharsets.UTF_8);}/*** 解密* @param encryptStr 加密字符串* @param password 密码* @param iv 初始向量* @param salt 盐值* @return* @throws Exception*/public static String decrypt(String encryptStr, String password, String iv, String salt) throws Exception {SecretKey secretKey = getAESKeyFromPassword(password.toCharArray(), Base64.decodeBase64(salt));return decrypt(Base64.decodeBase64(encryptStr), secretKey, Base64.decodeBase64(iv));}/*** 解密* @param encryptStr 加密字符串* @param key 秘钥* @param iv 初始向量* @return* @throws Exception*/public static String decrypt(String encryptStr, String key, String iv) throws Exception {SecretKey secretKey = new SecretKeySpec(Base64.decodeBase64(key), KEY_ALGORITHM);return decrypt(Base64.decodeBase64(encryptStr), secretKey, Base64.decodeBase64(iv));}}
pom依赖
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.15</version></dependency><!-- https://mvnrepository.com/artifact/commons-collections/commons-collections --><dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2.2</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency>
AES GCM算法实现相关推荐
- AES GCM 算法
AES-GCM算法是带认证和加密的算法,也即同时可以对给定的原文,生成加密数据和认证码. 加密方: plain_test key_128/key_256 iv/salt aad, 生成校验码的盐值 密 ...
- ecb gcm java 加密,AES GCM和ECB加密软件,附算法源码和工程文件
[实例简介] AesTestTool为加密软件,支持GCM 和 ECB两种模式 128bit秘钥 GCM算法是一个C++工程,"C++gcm算法工程"目录里面有源码 加密软件是用C ...
- C# 实现AES GCM加解密
// 使用的包 using NPOI.POIFS.Crypt;/// <summary> /// AES GCM 加密 /// </summary> /// <param ...
- C++ Openssl AES GCM 128bits代码示例,可wins10的visual studio 2017 中直接运行
C++ Openssl AES GCM 128bits代码示例,可wins直接运行 使用vcpkg安装64bits的openssl,本人当前的openssl为openssl-1.1.1d版本,wins ...
- 使用Crypto++的AES GCM对称加密
这里记录使用Crypto++的AES GCM对称加密的代码片段,可直接执行 运行环境:Windows, Visual Studio 2017 需安装Crypto++库,可使用cvpkg工具直接集成该库 ...
- Android报加密错误,在android中解密使用aes/gcm/nopadding加密的消息时出错
我目前正在使用aes/gcm/nopadding执行密码操作. 我的加密代码: fun encrypt(plainText: ByteArray, key: Key): ByteArray? { va ...
- AES AES/GCM/NoPadding 加密解密
public class AESUtils {public static final String algorithm = "AES";// AES/GCM/NoPadding: ...
- java gcm_JAVA中的AES GCM加密和解密
我正在尝试在JAVA中实现AES / GCM / NoPadding加密和解密.使用的密钥是来自接收方的公钥和发送方的私钥(ECDH)的共享密钥.加密效果很好(有无iv).但是,我无法解密...... ...
- RC4算法原理、Java实现RC4加密算法、DES AES RC4算法比较
DES AES RC4算法比较 根据密钥类型的不同,加密算法分为对称和非对称两种.对称加密系统是指加密和解密均采用同一把密钥. 对称加密算法是最常用的加密算法,优势在于算法公开,计算量小,加密效率高. ...
最新文章
- 深度学习 Optimizer 梯度下降优化算法总结
- [ 墨者学院 ] 命令执行——Bash漏洞分析溯源
- Reorder List
- sql 命令重启计算机,如何重启SQL服务
- ug中文字大小设置_UG与AutoCAD的数据转换,原来还有这么简单的方法
- 一个关于sql server索引与填充因子的链接
- 通达信手机版指标源码大全_通达信指标公式源码短炒买卖指标
- AutoJs 4.1.1 实战教程
- windows上查看MD5
- 2020COSMO时尚盛典即将闪耀启幕
- 2022年全球沥青毯市场前景分析及研究报告
- combo 技术简单介绍
- 用ASP.NET创建网络相册
- 2022年全球与中国智能白板市场现状及未来发展趋势
- 加密项目是否采用DAO模式 首先考量这8个因素
- [Java经典题目] 随机得到一个[ 1-100]之间的年龄
- 影响企业未来的十大管理理念
- 通过经纬度解析商圈Scala实现方式
- c语言实现小游戏-扫雷
- c语言整数编年历系统,作为程序员必须知道的编程语言编年史