Java Aes 加密 (AES/GCM/NoPadding方式)

上代码:

public class AesSecretUtil {


    /**
     * 加密方式
     */
    private static final String ALGORITHM = "AES";
    /**
     * keySize
     */
    private static final int KEY_SIZE = 128;

    /**
     * 算法/模式/填充
     */
    private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
     /**
     * 初始化向量使用的数组
     */
    private static final byte[] iv = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6};

    /**
     * 初始向量IV, 初始向量IV的长度规定为128位16个字节.
     */
    private static final GCMParameterSpec gcMParameterSpec;

    static {
        gcMParameterSpec = new GCMParameterSpec(128, iv);
        java.security.Security.setProperty("crypto.policy", "unlimited");
    }

      /**
     * 加密数据
     * @param key 秘钥
     * @param data 需加密的明文数据
     * @return 密文数据
     */
    public static String encrypt(String key, String data) throws Exception {
        if (StrUtil.isBlank(data)){
            return StrUtil.EMPTY;
        }
        KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
        generator.init(KEY_SIZE);
        SecretKey secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey,gcMParameterSpec);
        byte[] encryptedData = cipher.doFinal(data.getBytes());
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    /**
     * 解密数据
     * @param key 秘钥
     * @param encryptedData 需解密字符串
     * @return 明文数据
     */
    public static String decrypt(String key, String encryptedData) throws Exception {
        if (StrUtil.isBlank(encryptedData)){
            return StrUtil.EMPTY;
        }
        SecretKey secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKey,gcMParameterSpec);
        byte[] decryptedData = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
        return new String(decryptedData);
    }


}

这里用的初始化向量是固定的数组转换的,实际生产中,也可以使用随机数组进行加密解密,不过加密解密使用的初始化向量一定要相同。所以此时需要在数据库中存储需要加密解密数据的同时,也要存储初始化向量数据。类似于随机盐。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这个问题涉及到JS和Java加密解密实现,我会尽力回答。首先,AES-GCM是一种高级加密标准(Advanced Encryption Standard)的加密模式,它是一种块加密模式,可以提供加密和认证功能。而PKCS5Padding是一种填充模式,它可以把不满足块大小的数据填充到块大小,以满足加密算法的要求。 在Node.js中,可以使用node-forge库提供的API实现AES-GCM加密,示例代码如下: ```javascript const forge = require('node-forge'); // 加密 function encrypt(plaintext, key, iv) { const cipher = forge.cipher.createCipher('AES-GCM', key); cipher.start({ iv: iv }); cipher.update(forge.util.createBuffer(plaintext)); cipher.finish(); return { ciphertext: cipher.output.toHex(), tag: cipher.mode.tag.toHex() }; } const plaintext = 'Hello, world!'; const key = forge.random.getBytesSync(32); const iv = forge.random.getBytesSync(12); const encrypted = encrypt(plaintext, key, iv); console.log(encrypted); ``` 在Java中,可以使用javax.crypto库提供的API实现AES/GCM/PKCS5Padding解密,示例代码如下: ```java import javax.crypto.Cipher; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; public class Decryptor { public static String decrypt(String ciphertext, String key, String iv, String tag) throws Exception { byte[] ct = hexStringToByteArray(ciphertext); byte[] k = hexStringToByteArray(key); byte[] i = hexStringToByteArray(iv); byte[] t = hexStringToByteArray(tag); Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding"); SecretKeySpec keySpec = new SecretKeySpec(k, "AES"); GCMParameterSpec gcmSpec = new GCMParameterSpec(t.length * 8, i); cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmSpec); cipher.update(ct); cipher.updateAAD(t); byte[] pt = cipher.doFinal(); return new String(pt); } 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; } } ``` 以上代码仅供参考,具体实现需要根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值