📜  什么是Java AES 加密和解密?(1)

📅  最后修改于: 2023-12-03 14:49:10.542000             🧑  作者: Mango

什么是Java AES 加密和解密?

AES(Advanced Encryption Standard)是一种对称加密算法,是当前最常用的加密算法之一。Java中提供了对AES加密和解密的支持。在Java中使用AES加密和解密分为以下几个步骤:

生成密钥

使用Java内置的KeyGenerator类可以生成一个AES的密钥。以下是一个生成128位密钥的示例代码:

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
加密数据

实现AES加密的主要类是Cipher。它提供了加密和解密的功能。以下是一个加密数据的示例代码:

Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedData = cipher.doFinal(plainText.getBytes());

要注意的是,加密前的数据需要先转换成byte数组。

解密数据

解密数据与加密数据非常类似。以下是一个解密数据的示例代码:

Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedData = cipher.doFinal(encryptedData);
String plainText = new String(decryptedData);

与加密数据类似,解密后的数据也需要转换成相应的格式。

设置加密模式和填充方式

在加密和解密时,可以设置不同的加密模式和填充方式。以下是一些常见的加密模式和填充方式:

加密模式
  • ECB模式:电子密码本模式
  • CBC模式:密码分组链接模式
  • CFB模式:密码反馈模式
  • OFB模式:输出反馈模式
填充方式
  • NoPadding:不填充,加密前数据长度必须是16的整倍数
  • PKCS5Padding:以5个字节为一组进行填充(最多填充4个字节)
  • PKCS7Padding:以7个字节为一组进行填充
  • ISO10126Padding:填充的值为随机数

以下是一个使用CBC模式和PKCS5Padding填充方式的示例代码:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
byte[] encryptedData = cipher.doFinal(plainText.getBytes());

其中,IvParameterSpec是设置初始向量的类。要注意,初始向量的长度必须是16个字节。

示例代码

以下是一个使用AES进行加密和解密的完整示例代码:

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class AESUtil {
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, InvalidAlgorithmParameterException {
        String keyStr = "1234567890123456";
        String ivStr = "1234567890123456";
        String plainText = "Hello, World!";

        // 生成密钥
        SecretKey secretKey = new SecretKeySpec(keyStr.getBytes(StandardCharsets.UTF_8), "AES");

        // 设置初始向量
        byte[] iv = ivStr.getBytes(StandardCharsets.UTF_8);

        // 加密数据
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
        byte[] encryptedData = cipher.doFinal(plainText.getBytes());

        // 输出加密后的数据
        System.out.println("加密后的数据:" + new String(encryptedData));

        // 解密数据
        cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
        byte[] decryptedData = cipher.doFinal(encryptedData);

        // 输出解密后的数据
        System.out.println("解密后的数据:" + new String(decryptedData));
    }
}

以上代码中,我们使用了AES/CBC/PKCS5Padding模式对数据进行了加密和解密。其中,keyStr和ivStr是长度为16个字节的字符串,作为加密和解密时的密钥和初始向量。plainText是要加密的明文。在运行时,输出的结果如下:

加密后的数据:n83z6ZZl7+i614y/KOGK1Q==
解密后的数据:Hello, World!

可以看出,数据经过加密和解密后,内容没有发生改变。