Java 实现 AES 对称加密算法的加解密

前言

文章字数比较多,可直接查看代码:源码地址,文中描述有误的地方欢迎各位大神指导。

一、对称加密算法简介

1.对称加密

采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。

对称加密特点:

  • 加密速度快,可以加密大文件。
  • 密文可逆,一旦密钥文件泄漏,就会导致数据暴露。
  • 加密后编码表找不到对应字符会出现乱码。
  • 一般结合Base64使用。

2.加密模式

ECB

ECB(Electronic codebook):电子密码本,需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密。

  • 优点 : 可以并行处理数据。
  • 缺点 : 同样的原文生成同样的密文,不能很好的保护数据。

CBC

CBC(Cipher-block chaining):密码块链接,每个明文块先与前一个密文块进行异或,然后再进行加密,在这种方法中,每个密文块都依赖于它前面的所有明文块。

  • 优点 : 同样的原文生成的密文不一样。
  • 缺点 : 串行处理数据。

3.填充模式

当需要按块处理的数据,数据长度不符合块处理需求时,按照一定的方法填充满块长的规则。

NoPadding

  • 不填充,在AES加密算法下,要求原文长度必须是16byte的整数倍。

PKCS5Padding

  • 数据块的大小为8位不够就补足。

二、AES 加解密代码实例

1.生成 AES 密钥

  • AES 密钥长度默认只支持128、192、256 这三种长度,不合法的密钥长度程序会抛出异常。
  • 生成 AES 密钥时会使用到随机数生成器,可以指定不同的随机数算法,也可以在创建随机数生成器时指定 seed。
  • 初始化算法生成器时,如果不指定随机数生成器默认使用 new SecureRandom()。

代码如下:

    public static SecretKey generateSecretKey(int keysize) throws NoSuchAlgorithmException {
        // 校验密钥长度
        if (keysize != 128 && keysize != 192 && keysize != 256) {
            keysize = 128;
        }
        // 创建安全随机数生成器(SHA1PRNG)
        final SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        // 创建 AES 算法生成器(AES)
        final KeyGenerator generator = KeyGenerator.getInstance("AES");
        // 初始化算法生成器
        generator.init(keysize, random);
        return generator.generateKey();
    }

2.AES 加解密

代码如下:

    public static void main(String[] args) throws Exception {
        final String data = "test";
        final SecretKey secretKey = generateSecretKey(128);

        final byte[] encrypt = encrypt(secretKey.getEncoded(), data.getBytes());
        final byte[] decrypt = decrypt(secretKey.getEncoded(), encrypt);
        System.out.println(new String(decrypt));
    }
    
    /**
     * AES 加密
     *
     * @param aseKey 密钥
     * @param plain 加密原文
     * @return 密文
     */
    public static byte[] encrypt(byte[] aseKey, byte[] plain) throws Exception {
        final SecretKey secretKey = new SecretKeySpec(aseKey, "AES");
        final Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return cipher.doFinal(plain);
    }

    /**
     * AES 解密
     *
     * @param aseKey AES 密钥
     * @param encrypted 解密密文
     * @return 原文
     */
    public static byte[] decrypt(byte[] aseKey, byte[] encrypted) throws Exception {
        final SecretKey secretKey = new SecretKeySpec(aseKey, "AES");
        final Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        return cipher.doFinal(encrypted);
    }

3.AES + nonce 加解密

注意在使用 nonce 时,nonce 的长度不能超过 128,不然程序会抛出异常。

代码如下:

    public static void main(String[] args) throws Exception {
        final String data = "test";
        final byte[] nonce = generatorNonce(16);
        final SecretKey secretKey = generateSecretKey(128);

        final byte[] encrypt = encrypt(secretKey.getEncoded(), data.getBytes(), nonce);
        final byte[] decrypt = decrypt(secretKey.getEncoded(), encrypt, nonce);
        System.out.println(new String(decrypt));
    }

    /**
     * AES 加密
     *
     * @param aseKey AES 密钥
     * @param plain 加密原文
     * @param nonce 随机值
     * @return 密文
     */
    public static byte[] encrypt(byte[] aseKey, byte[] plain, byte[] nonce) throws Exception {
        final SecretKey secretKeySpec = new SecretKeySpec(aseKey, "AES");
        final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        final GCMParameterSpec zeroIv = new GCMParameterSpec(128, nonce);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, zeroIv);
        return cipher.doFinal(plain);
    }

    /**
     * AES 解密
     *
     * @param aseKey AES 密钥
     * @param encrypted 解密密文
     * @param nonce 随机值
     * @return 原文
     */
    public static byte[] decrypt(byte[] aseKey, byte[] encrypted, byte[] nonce) throws Exception {
        final SecretKeySpec secretKeySpec = new SecretKeySpec(aseKey, "AES");
        final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        final GCMParameterSpec zeroIv = new GCMParameterSpec(128, nonce);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, zeroIv);
        return cipher.doFinal(encrypted);
    }

    /**
     * 获取随机值
     *
     * @param len 随机值长度
     */
    public static byte[] generatorNonce(int len) {
        byte[] values = new byte[len];
        final SecureRandom random = new SecureRandom();
        random.nextBytes(values);
        return values;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java AES256加密解密是一种常用的对称加密算法,它使用256位的密钥对数据进行加密解密。下面是Java中使用AES256进行加密解密的基本步骤: 1. 导入相关的类库: ```java import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; ``` 2. 定义加密解密方法: ```java public class AESUtil { private static final String ALGORITHM = "AES"; private static final TRANSFORMATION = "AES/ECB/PKCS5Padding"; public static String encrypt(String data, String key) throws Exception { SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM); Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)); return Base64.getEncoder().encodeToString(encryptedBytes); } public static String decrypt(String encryptedData, String key) throws Exception { SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM); Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData)); return new String(decryptedBytes, StandardCharsets.UTF_8); } } ``` 3. 使用加密解密方法: ```java public class Main { public static void main(String[] args) { try { String data = "Hello, World!"; String key = "0123456789abcdef0123456789abcdef"; // 256位密钥 String encryptedData = AESUtil.encrypt(data, key); System.out.println("加密后的数据:" + encryptedData); String decryptedData = AESUtil.decrypt(encryptedData, key); System.out.println("解密后的数据:" + decryptedData); } catch (Exception e) { e.printStackTrace(); } } } ``` 以上代码演示了如何使用Java进行AES256加密解密。需要注意的是,密钥的长度必须是256位(32字节),并且在实际应用中应该使用安全的方式来保存和传输密钥。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值