栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

AES GCM算法实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

AES GCM算法实现

当前业界敏感信息加密使用AES较多,GCM模式兼具效率和安全性,故选择使用该模式。

注意

我们经常使用256位秘钥,因为美国的安全管控,jdk8的较老版本安全策略不支持256位秘钥,需替换jdkjrelibsecurity 下的安全策略文件local_policy.jar 和US_export_policy.jar

java 1.8.0_151到1.8.0_161版本已经包含了不同的安全策略,需要修改jdkjrelibsecurityjava.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;


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;

    
    public static byte[] getRandomNonce(int numBytes) {
        byte[] nonce = new byte[numBytes];
        new SecureRandom().nextBytes(nonce);
        return nonce;
    }

    
    public static String generateSalt() {
        byte[] salt = getRandomNonce(SALT_LENGTH_BYTE);
        return Base64.encodeBase64String(salt);
    }

    
    public static String generateIv() {
        byte[] iv = getRandomNonce(IV_LENGTH_BYTE);
        return Base64.encodeBase64String(iv);
    }

    
    public static SecretKey getAESKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGen = KeyGenerator.getInstance(KEY_ALGORITHM);
        keyGen.init(AES_KEY_BIT, SecureRandom.getInstanceStrong());
        return keyGen.generateKey();
    }

    
    public static String generateAESKey() throws NoSuchAlgorithmException {
        return Base64.encodeBase64String(getAESKey().getEncoded());
    }

    
    public static SecretKey getAESKeyFromPassword(char[] password, byte[] salt)
        throws NoSuchAlgorithmException, InvalidKeySpecException {

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        // iterationCount = 65536
        KeySpec spec = new PBEKeySpec(password, salt, 65536, AES_KEY_BIT);
        SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), KEY_ALGORITHM);
        return secret;

    }

    
    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;
    }

    
    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);
    }

    
    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);
    }

    
    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);
    }

    
    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));
    }

    
    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依赖

        
        
            commons-codec
            commons-codec
            1.15
        

        
        
            commons-collections
            commons-collections
            3.2.2
        

        
        
            org.apache.commons
            commons-lang3
            3.12.0
        

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1014386.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号