AES加密解密(GCM模式)

该文章已生成可运行项目,

import javax.crypto.Cipher;
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.Base64;

/**
 * AES加密解密
 *
 * @author ning
 * @since 2023/9/18 14:23
 */

public class AESEncrypt {


    /**
     * 加密
     */
    public static String getEncrypt(String userProvidedPassword) throws Exception {
        // 生成128位(16字节)AES密钥
        byte[] keyBytes = new byte[16];
        // 创建SecretKey
        SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");

        // 初始化Cipher为AES/GCM/NoPadding,因为GCM不需要额外的填充
        // GCM需要一个额外的参数来指定认证标签的长度(通常为128位)
        int tagLength = 128; // 认证标签的长度,以位为单位
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

        // 生成一个安全的随机IV
        SecureRandom random = new SecureRandom();
        byte[] iv = new byte[12]; // GCM需要96位(12字节)的IV
        random.nextBytes(iv);
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(tagLength, iv);
        // 初始化Cipher
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmParameterSpec);
        // 加密密码
        byte[] encryptedPasswordBytes = cipher.doFinal(userProvidedPassword.getBytes(StandardCharsets.UTF_8));

        // nonce是必需的,因为GCM在解密时需要它。将其附加到密文的前面是一个常见的做法。
        // 这里简单起见,我们将nonce和密文合并,但在实际应用中,您可能需要一种更复杂的方法来处理它们。
        // 加密结果包括IV和密文,我们可以将它们组合在一起
        ByteBuffer result = ByteBuffer.allocate(iv.length + encryptedPasswordBytes.length);
        result.put(iv);
        result.put(encryptedPasswordBytes);
        // 将加密后的密码和nonce编码为Base64
        return Base64.getEncoder().encodeToString(result.array());

    }


    /**
     * 解密
     */
    public static String getDecode(String encryptedPassword) throws Exception{
        // 生成128位(16字节)AES密钥
        byte[] keyBytes = new byte[16];
        // 创建SecretKey
        SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");

        // 假设encryptedPassword是Base64编码的,并且包含了nonce和密文
        byte[] encodedData = Base64.getDecoder().decode(encryptedPassword);

        // 提取nonce(IV),假设它位于密文的最前面
        byte[] nonce = new byte[12]; // GCM的nonce长度通常为96位(12字节)
        System.arraycopy(encodedData, 0, nonce, 0, nonce.length);

        // 提取密文,跳过nonce
        byte[] cipherText = new byte[encodedData.length - nonce.length];
        System.arraycopy(encodedData, nonce.length, cipherText, 0, cipherText.length);

        // 初始化Cipher为AES/GCM/NoPadding,并设置nonce
        int tagLength = 128; // 认证标签的长度,以位为单位
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(tagLength, nonce);

        // 初始化Cipher为解密模式
        cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmParameterSpec);

        // 解密密码
        byte[] decryptedPasswordBytes = cipher.doFinal(cipherText);

        // 将解密后的密码转换为字符串
        return new String(decryptedPasswordBytes, StandardCharsets.UTF_8);

    }
}

本文章已经生成可运行项目
### AES-GCM 实现与使用 AES-GCM(Galois/Counter Mode)是一种组合模式,它同时提供数据保密性和完整性验证。这种模式基于计数器模式(CTR),并附加了一个称为 GMAC 的认证机制。 #### Python 中实现 AES-GCM 加密解密 Python 提供了 `cryptography` 库来简化高级加密操作: ```python from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend import os def aes_gcm_encrypt(key, plaintext): iv = os.urandom(12) # Generate a random IV of length 12 bytes cipher = Cipher(algorithms.AES(key), modes.GCM(iv), backend=default_backend()) encryptor = cipher.encryptor() ciphertext = encryptor.update(plaintext.encode()) + encryptor.finalize() return { "iv": iv, "tag": encryptor.tag, "ciphertext": ciphertext } def aes_gcm_decrypt(key, encrypted_data): cipher = Cipher(algorithms.AES(key), modes.GCM( encrypted_data["iv"], encrypted_data["tag"]), backend=default_backend() ) decryptor = cipher.decryptor() decrypted_text = decryptor.update(encrypted_data["ciphertext"]) + decryptor.finalize() return decrypted_text.decode() # Example Usage key = b'Sixteen byte key' # Must be either 16 or 32 bytes long for AES-128/AES-256 respectively. message = 'Hello World!' encrypted_message = aes_gcm_encrypt(key, message) decrypted_message = aes_gcm_decrypt(key, encrypted_message) print(f"Original Message: {message}") print(f"Decrypted Message: {decrypted_message}") ``` 上述代码展示了如何利用 PyCryptodome 创建一个简单的 AES-GCM 加密函数以及相应的解密过程[^1]。 #### 安全注意事项 当部署 AES-GCM 方案时需要注意以下几点: - 密钥管理至关重要;应采用安全的方式存储和传输密钥。 - 初始化向量 (IV) 对于每次加密都应该是唯一的,并且可以公开传递给接收方用于解密。 - 认证标签(Tag)应该被发送者附带在消息之后一起传送给接收者以便后者能够验证消息的真实性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值