关于数据AES加密的使用

因博主最近接触到敏感数据保护,选择使用AES进行加密,记录一下.

1 AES概述

1 引入概述

密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。

这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。

DES使用的是56位密钥,AES可以使用128、192、和256位密钥

2 加密类型

AES机密属于对称加密,即通过相应的密钥,可以解析出明文.

3 使用场景

AES现在广泛用于金融财务,敏感数据保护等领域。

2 AES加密方式

AES加密中, 密钥的长度有三种: 128 192 256 .

1 填充

明文不是128位(16字节)的则需要填充,在明文某个地方补充到16个字节整数倍的长度,加解密时需要采用同样的填充方式,否则无法解密.


NoPadding

不进行填充,但是这里要求明文必须要是16个字节的整数倍,需要用户自己实现.

PKCS5Padding(默认)

在明文的末尾进行填充,填充的数据是当前和16个字节相差的数量.

注:使用PKCS5Padding填充时,最后一个字节肯定为填充数据和16字节的差值,所以在解密后可以准确删除填充的数据.

2 模式

ECB模式(默认) 电码本模式

根据密钥的位数,将数据分成不同的块进行加密,加密完成后,再将加密后的数据拼接起来.

CBC模式 密码分组链接模式

ECB模式的密文块都是相同,这是一个缺点.CBC的模式引入了一个初始向量概念,该向量必须是一个与密钥长度相等的数据,在第一次加密前,会使用初始化向量与第一块数据做异或运算,生成的新数据再进行加密,加密第二块之前,会拿第一块的密文数据与第二块明文进行异或运算后再进行加密,以此类推,解密时也是在解密后,进行异或运算,生成最终的明文.

3 常用案列

AES加密常用模板

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * @Description
 * @date 2021/8/21
 */
public class AESTest {
    
    

    /**
     * key 密钥 可以用26个字母和数字组成 使用AES-128-CBC加密模式,key需要为16位
     */
    private static final String key="1234567812345678";
    /**
     * iv 偏移量,长度16
     */
    private static final String iv ="1234567887654321";

    /**
     * @Description AES算法加密明文
     * @param data 明文
     * @return 密文
     */
    public static String encryptAES(String data) throws Exception {
    
    
        try {
    
    
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            int blockSize = cipher.getBlockSize();
            byte[] dataBytes = data.getBytes();
            int plaintextLength = dataBytes.length;

            if (plaintextLength % blockSize != 0) {
    
    
                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
            }

            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
            // CBC模式,需要一个向量iv,可增加加密算法的强度
            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");

            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
            byte[] encrypted = cipher.doFinal(plaintext);

            // BASE64做转码
            return AESTest.encode(encrypted).trim();

        } catch (Exception e) {
    
    
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @Description AES算法解密密文
     * @param data 密文
     * @return 明文
     */
    public static String decryptAES(String data) throws Exception {
    
    
        try
        {
    
    
            // 先用base64解密
            byte[] encrypted1 = AESTest.decode(data);

            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());

            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);

            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original);
            return originalString.trim();
        }
        catch (Exception e) {
    
    
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 编码
     * @param byteArray
     * @return
     */
    public static String encode(byte[] byteArray) {
    
    
        return new String(new Base64().encode(byteArray));
    }

    /**
     * 解码
     * @param base64EncodedString
     * @return
     */
    public static byte[] decode(String base64EncodedString) {
    
    
        return new Base64().decode(base64EncodedString);
    }

    public static void main(String[] args) throws Exception {
    
    
        // 明文
        String password = "777788889999";

        // 加密
        String encodePassword = AESTest.encryptAES(password);
        System.out.println(encodePassword);

        // 解密
        String decodePassword = AESTest.decryptAES(encodePassword);
        System.out.println(decodePassword);

    }

}

猜你喜欢

转载自blog.csdn.net/ABestRookie/article/details/119879255