AES是一种对称加密技术 即加密密钥和解密密钥相同,在密码学中又称Rijndael加密法,为比利时密码学家Joan Daemen和Vincent Rijmen所设计



一、加密模式

4种分别是:CBC、CFB、OFB、ECB

3种需要向量参数:CBC、CFB、OFB模式;

1种不需要向量参数:ECB模式;


ECB模式是最基本的加密模式,最容易被破解,CBC、CFB、OFB模式的加密过程添加向量后会更加安全。



二、加密填充

5种分别是:pkcs5padding、pkcs7padding、zeropadding、iso10126、ansix923


AES是对数据进行大小相同的分块分割,再进行分块加密;

1.当先对数据分块后,最后一块的数据不一定是完整的,利用填充补齐数据。

2.当先对数据分块后,数据块都是完整的,利用填充再生成一整块数据。


pkcs5padding:固定块的大小为8bytes(64位)

pkcs7padding:块的大小可以在1-255bytes之间。



三、密钥长度

只能是128、192或256位。

128位对应16个字节(8位一个字节)、192位对应24个字节、256位对应32个字节;位数越高加密强度越大, 但加密效率越低。


128:aaaaaaaaaaaaaaaa

192:aaaaaaaaaaaaaaaacccccccc

256:aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb



四、输出

2种分别是:base64、hex

对加密后的字节进行base64编码或hex编码



五、Java加解密

以下示例采用:AES/CBC/PKCS5Padding模式,128位秘钥长度和向量长度


(1) 加解密

package com.xxxx.utils;


import org.bouncycastle.util.encoders.Hex;

import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;


/**

 * AES 加解密

 *

 * AES/CBC/PKCS5Padding

 */

public class AesUtils {


    /**

     * 算法的名称

     */

    private static final String AES = "AES";


    /**

     * 默认 AES/CBC/PKCS5Padding

     *

     * 算法:AES

     * 模式:CBC; 其中CBC、CFB模式需要向量;OFB模式不需要向量

     * 填充:PKCS5Padding

     */

    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";


    /**

     * 编码 utf-8

     */

    private static final String UTF_8 = "utf-8";


    /**

     * 加密

     *

     * @param needEncryptStr 待加密字符串

     * @param key 加密key

     * @param iv 向量

     * @return

     * @throws Exception

     */

    public static String encrypt(String needEncryptStr, String key, String iv) throws Exception {

        byte[] raw = key.getBytes(UTF_8);

        //设置秘钥

        SecretKeySpec keySpec = new SecretKeySpec(raw, AES);

        //设置向量

        IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());

        //初始化加密方式  Cipher.ENCRYPT_MODE 加密

        Cipher cipher = Cipher.getInstance(ALGORITHM);

        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

        //加密;   设置为utf-8, 防止中文和英文混合

        byte[] encrypted = cipher.doFinal(needEncryptStr.getBytes(UTF_8));

        //对加密结果HEX编码; 解密时也就需要使用HEX解码;

        byte[] encode = Hex.encode(encrypted);

        // 使用BASE64做转码

        // return new BASE64Encoder().encode(encode);

        return new String(encode).toUpperCase();

    }


    /**

     * 解密

     *

     * @param needDecryptStr 秘钥

     * @param key 秘钥

     * @param iv   向量

     * @param needDecryptStr

     * @return

     * @throws Exception

     */

    public static String decrypt(String needDecryptStr, String key, String iv) throws Exception {

        byte[] raw = key.getBytes(UTF_8);

        //设置秘钥

        SecretKeySpec keySpec = new SecretKeySpec(raw, AES);

        //设置向量

        IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());

        //初始化解密方式  Cipher.DECRYPT_MODE 解密

        Cipher cipher = Cipher.getInstance(ALGORITHM);

        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);


        //获取HEX的解码,因为在是加密过程中采用了HEX的编码,所以此步骤需要HEX的解码

        //如果在是加密过程中采用了base64的编码,此步骤就需要base64的解码,

        //HEX和base64 使用一种即可,但需要保持一致

        byte[] encrypted1 = Hex.decode(needDecryptStr);

        // 先用base64解密。与上一行HEX两者选其一。

        // byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);


        //解密

        byte[] original = cipher.doFinal(encrypted1);

        return new String(original, UTF_8);

    }

}

 

(2) 调用

try{

    String needEncryptStr = "A1B2我们";

    String key = "aaaaaaaaaaaaaaaa";

    String iv  = "aaaaaaaaaaaaaaaa";

    //加密

    String encryptStr = AesUtils1.encrypt(needEncryptStr, key, iv);

    //解密

    String decryptStr = AesUtils1.decrypt(encryptStr, key, iv);

}catch (Exception e){

    

}

 



————————————————

版权声明:本文为CSDN博主「预立科技」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/sinat_16998945/article/details/126829868