当前业界敏感信息加密使用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算法实现相关推荐

  1. AES GCM 算法

    AES-GCM算法是带认证和加密的算法,也即同时可以对给定的原文,生成加密数据和认证码. 加密方: plain_test key_128/key_256 iv/salt aad, 生成校验码的盐值 密 ...

  2. ecb gcm java 加密,AES GCM和ECB加密软件,附算法源码和工程文件

    [实例简介] AesTestTool为加密软件,支持GCM 和 ECB两种模式 128bit秘钥 GCM算法是一个C++工程,"C++gcm算法工程"目录里面有源码 加密软件是用C ...

  3. C# 实现AES GCM加解密

    // 使用的包 using NPOI.POIFS.Crypt;/// <summary> /// AES GCM 加密 /// </summary> /// <param ...

  4. C++ Openssl AES GCM 128bits代码示例,可wins10的visual studio 2017 中直接运行

    C++ Openssl AES GCM 128bits代码示例,可wins直接运行 使用vcpkg安装64bits的openssl,本人当前的openssl为openssl-1.1.1d版本,wins ...

  5. 使用Crypto++的AES GCM对称加密

    这里记录使用Crypto++的AES GCM对称加密的代码片段,可直接执行 运行环境:Windows, Visual Studio 2017 需安装Crypto++库,可使用cvpkg工具直接集成该库 ...

  6. Android报加密错误,在android中解密使用aes/gcm/nopadding加密的消息时出错

    我目前正在使用aes/gcm/nopadding执行密码操作. 我的加密代码: fun encrypt(plainText: ByteArray, key: Key): ByteArray? { va ...

  7. AES AES/GCM/NoPadding 加密解密

    public class AESUtils {public static final String algorithm = "AES";// AES/GCM/NoPadding: ...

  8. java gcm_JAVA中的AES GCM加密和解密

    我正在尝试在JAVA中实现AES / GCM / NoPadding加密和解密.使用的密钥是来自接收方的公钥和发送方的私钥(ECDH)的共享密钥.加密效果很好(有无iv).但是,我无法解密...... ...

  9. RC4算法原理、Java实现RC4加密算法、DES AES RC4算法比较

    DES AES RC4算法比较 根据密钥类型的不同,加密算法分为对称和非对称两种.对称加密系统是指加密和解密均采用同一把密钥. 对称加密算法是最常用的加密算法,优势在于算法公开,计算量小,加密效率高. ...

最新文章

  1. 深度学习 Optimizer 梯度下降优化算法总结
  2. [ 墨者学院 ] 命令执行——Bash漏洞分析溯源
  3. Reorder List
  4. sql 命令重启计算机,如何重启SQL服务
  5. ug中文字大小设置_UG与AutoCAD的数据转换,原来还有这么简单的方法
  6. 一个关于sql server索引与填充因子的链接
  7. 通达信手机版指标源码大全_通达信指标公式源码短炒买卖指标
  8. AutoJs 4.1.1 实战教程
  9. windows上查看MD5
  10. 2020COSMO时尚盛典即将闪耀启幕
  11. 2022年全球沥青毯市场前景分析及研究报告
  12. combo 技术简单介绍
  13. 用ASP.NET创建网络相册
  14. 2022年全球与中国智能白板市场现状及未来发展趋势
  15. 加密项目是否采用DAO模式 首先考量这8个因素
  16. [Java经典题目] 随机得到一个[ 1-100]之间的年龄
  17. 影响企业未来的十大管理理念
  18. 通过经纬度解析商圈Scala实现方式
  19. c语言实现小游戏-扫雷
  20. c语言整数编年历系统,作为程序员必须知道的编程语言编年史

热门文章

  1. html 语义化的理解
  2. phone开发基础教程
  3. sql 排名前十_全国人口净流入前十排名,珠三角占据4席!
  4. xp黑屏怎么办 这儿有解决办法 专治XP黑屏
  5. 如何把抖音粉丝加到微信里?一文讲透其中的秘密
  6. 拿你的什么来吸引微信粉丝
  7. 【弹跳闯关小游戏,c++】
  8. 【开发笔记】td标签内容过长时解决办法
  9. 面试网易的前端工程有多难?问啥啥不会?
  10. mysql下载与安装过程