AESGCM256 加密解密

本文介绍了一个使用Java实现的AES-GCM 256位加密/解密工具,包括固定和随机盐的处理,以及生成随机盐的方法。着重于AES算法和GCM模式的应用,适用于安全的数据传输和存储。
package xxxxx

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;


public class AESUtil {
    private static Logger logger = LoggerFactory.getLogger(AESUtil.class);


    /**
     * 算法
     */
    private static final String ALGORITHMS = "AES/GCM/PKCS5Padding";

    /**
     * 加密
     * @param fixedSalt 固定salt
     * @param randomSalt 随机salt
     * @param content 要加密的内容
     * @return
     */
    public static String encryptWithSalt(String fixedSalt, String randomSalt, String content) {
        try {
            if (StringUtils.isEmpty(fixedSalt) || StringUtils.isEmpty(randomSalt)) {
                throw new Exception("AESGCM256加密异常,检查文本或密钥");
            }
            SecretKey secretKey = new SecretKeySpec(hexStringToByteArray(fixedSalt + randomSalt), "AES");
            Cipher cipher = Cipher.getInstance(ALGORITHMS);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] iv = cipher.getIV();
            assert iv.length == 12;// 偏移参数及长度要在解密的时候保持一致
            byte[] encryptData = cipher.doFinal(content.getBytes());
            assert encryptData.length == content.getBytes().length + 16;
            byte[] message = new byte[12 + content.getBytes().length + 16];
            System.arraycopy(iv, 0, message, 0, 12);
            System.arraycopy(encryptData, 0, message, 12, encryptData.length);
            return Base64.encodeBase64String(message);
        } catch (Exception e) {
            logger.error("AESGCM256加密文本处理失败,error:{}", e);
        }
        return null;
    }

    /**
     * 解密
     * @param fixedSalt 固定salt
     * @param randomSalt 随机salt
     * @param encryptedContent 加密后的内容
     * @return
     */
    public static String decryptWithSalt(String fixedSalt, String randomSalt, String encryptedContent) {
        try {
            if (StringUtils.isEmpty(fixedSalt) || StringUtils.isEmpty(randomSalt)) {
                throw new Exception("AESGCM256解密异常,检查文本或密钥");
            }
            Cipher cipher = Cipher.getInstance(ALGORITHMS);
            SecretKey key = new SecretKeySpec(hexStringToByteArray(fixedSalt + randomSalt), "AES");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] message = Base64.decodeBase64(encryptedContent);
            // 这里的12和16是加密的时候设置的偏移参数及加密长度
            if (message.length < 12 + 16) throw new IllegalArgumentException();
            GCMParameterSpec params = new GCMParameterSpec(128, message, 0, 12);
            cipher.init(Cipher.DECRYPT_MODE, key, params);
            byte[] decryptData = cipher.doFinal(message, 12, message.length - 12);
            String decript = new String(decryptData);
            return decript;
        } catch (Exception e) {
            logger.error("AESGCM256解密文本处理失败,error:{}", e);
        }
        return null;
    }


    private static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }


    /**
     * 128位的随机盐进行base64加密
     * @return
     */
    public static String generateRandomSalt() throws java.security.NoSuchAlgorithmException{
        KeyGenerator generator = KeyGenerator.getInstance("AES");
        //初始化密钥生成器,AES要求密钥长度为128位、192位、256位
        generator.init(128);
        SecretKey secretKey = generator.generateKey();
        return Base64.encodeBase64String(secretKey.getEncoded());

    }
    public static void main(String[] args) throws java.security.NoSuchAlgorithmException{

        KeyGenerator generator = KeyGenerator.getInstance("AES");
        //初始化密钥生成器,AES要求密钥长度为128位、192位、256位
        generator.init(128);
        String password = "";
        SecretKey secretKey = generator.generateKey();
        String objectSalt = Base64.encodeBase64String(secretKey.getEncoded());
        System.out.println(objectSalt);

        SecretKey secretKey2 = generator.generateKey();
        String secretSalt = Base64.encodeBase64String(secretKey2.getEncoded());
        System.out.println(secretSalt);
        //初始化密钥生成器,AES要求密钥长度为128位、192位、256位
        String encryptContent = AESUtil.encryptWithSalt(objectSalt,secretSalt,password);
        logger.info(password);
        logger.info(encryptContent);
        String orignPassword = AESUtil.decryptWithSalt(objectSalt,secretSalt,encryptContent);
        logger.info(orignPassword);
    }
}

### AES GCM 加密解密 示例代码 AES/GCM/NoPadding 是一种现代加密方式,结合了对称加密算法 AES 和认证加密模式 GCM,同时不使用填充[^1]。以下是基于不同编程语言的 AES GCM 加密解密示例代码。 #### Python 实现 AES GCM 加密解密 ```python from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend import os def aes_gcm_encrypt(data, key): iv = os.urandom(12) # 生成随机初始化向量 cipher = Cipher(algorithms.AES(key), modes.GCM(iv), backend=default_backend()) encryptor = cipher.encryptor() ciphertext = encryptor.update(data.encode()) + encryptor.finalize() return (iv, ciphertext, encryptor.tag) def aes_gcm_decrypt(iv, ciphertext, tag, key): cipher = Cipher(algorithms.AES(key), modes.GCM(iv, tag), backend=default_backend()) decryptor = cipher.decryptor() plaintext = decryptor.update(ciphertext) + decryptor.finalize() return plaintext.decode() # 示例 key = os.urandom(32) # 256-bit 密钥 data = "Hello, AES GCM!" iv, ciphertext, tag = aes_gcm_encrypt(data, key) decrypted_data = aes_gcm_decrypt(iv, ciphertext, tag, key) print(f"原始数据: {data}") print(f"加密后: {ciphertext}") print(f"解密后: {decrypted_data}") ``` #### JavaScript 实现 AES GCM 加密解密 ```javascript const crypto = require('crypto'); function aesGcmEncrypt(data, key) { const iv = crypto.randomBytes(12); // 12 字节 IV const cipher = crypto.createCipheriv('aes-256-gcm', key, iv); let encrypted = cipher.update(data, 'utf8', 'hex'); encrypted += cipher.final('hex'); const tag = cipher.getAuthTag(); return { iv: iv.toString('hex'), encrypted, tag: tag.toString('hex') }; } function aesGcmDecrypt(iv, encrypted, tag, key) { const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(iv, 'hex')); decipher.setAuthTag(Buffer.from(tag, 'hex')); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } // 示例 const key = crypto.randomBytes(32); // 256-bit 密钥 const data = "Hello, AES GCM!"; const encryptedData = aesGcmEncrypt(data, key); const decryptedData = aesGcmDecrypt(encryptedData.iv, encryptedData.encrypted, encryptedData.tag, key); console.log(`原始数据: ${data}`); console.log(`加密后: ${encryptedData.encrypted}`); console.log(`解密后: ${decryptedData}`); ``` #### PHP 实现 AES GCM 加密解密 PHP 中可以使用 `openssl_encrypt` 和 `openssl_decrypt` 函数实现 AES GCM 加密解密[^3]。 ```php <?php class AesGcm { private const SECRETKEY = "1234567890abcdef"; // 16 字节密钥 public static function encrypt($data) { $cipher = "aes-128-gcm"; $ivlen = openssl_cipher_iv_length($cipher); $iv = openssl_random_pseudo_bytes($ivlen); $tag = ""; $encrypted = openssl_encrypt($data, $cipher, self::SECRETKEY, OPENSSL_RAW_DATA, $iv, $tag); return base64_encode($iv . $encrypted . $tag); } public static function decrypt($encryptedData) { $cipher = "aes-128-gcm"; $data = base64_decode($encryptedData); $ivlen = openssl_cipher_iv_length($cipher); $iv = substr($data, 0, $ivlen); $tag = substr($data, strlen($data) - 16, 16); $encrypted = substr($data, $ivlen, -16); return openssl_decrypt($encrypted, $cipher, self::SECRETKEY, OPENSSL_RAW_DATA, $iv, $tag); } } // 示例 $data = "Hello, AES GCM!"; $encryptedData = AesGcm::encrypt($data); $decryptedData = AesGcm::decrypt($encryptedData); echo "原始数据: " . $data . "\n"; echo "加密后: " . $encryptedData . "\n"; echo "解密后: " . $decryptedData . "\n"; ?> ``` ### 注意事项 - 在实际应用中,密钥应妥善保管,避免泄露[^2]。 - 使用 GCM 模式时,必须确保初始化向量(IV)的唯一性,以防止重放攻击或重复加密问题[^1]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值