AES CBC对称加密(JAVA PKCS#7填充算法)

AES CBC对称加密(JAVA PKCS#7填充算法)
package cn.lettin.common.aes;

import cn.lettin.ecc.Base64Utils;

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

/**
 * @Author : ZhangYunXin
 * @CreateDate : 2023/4/7 10:45
 * @Description : Aes工具类
 */
public class AesUtils {
    private static final String AES = "AES";
    private static final String AES_CBC_NO = "AES/CBC/NoPadding";

    /**
     * 对明文进行加密
     *
     * @param secretKey
     * @param originalData
     * @param iv
     * @return
     */
    public static String encrypt(String secretKey, String originalData, String iv) throws Exception {
        // 设置解密模式为AES的CBC模式
        Cipher cipher = Cipher.getInstance(AES_CBC_NO);
        // 解析密钥和偏移量
        SecretKeySpec keySpec = new SecretKeySpec(Base64Utils.decode(secretKey), AES);
        IvParameterSpec ivSpec = new IvParameterSpec(Base64Utils.decode(iv));
        // 初始化加密 设置为解密模式
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

        ByteGroup byteCollector = new ByteGroup();
        // 原文字节
        byteCollector.addBytes(originalData.getBytes());
        // 增加补位字符
        byteCollector.addBytes(PKCS7Encoder.encode(byteCollector.size()));
        // 加密
        byte[] bytes = cipher.doFinal(byteCollector.toBytes());
        // 返回加密结果
        return Base64Utils.encode(bytes);
    }

    /**
     * 对密文进行解密
     *
     * @param secretKey
     * @param encryptedData
     * @param iv
     * @return
     */
    public static String decrypt(String secretKey, String encryptedData, String iv) throws Exception {
        // 设置解密模式为AES的CBC模式
        Cipher cipher = Cipher.getInstance(AES_CBC_NO);
        // 解析密钥和偏移量
        SecretKeySpec keySpec = new SecretKeySpec(Base64Utils.decode(secretKey), AES);
        IvParameterSpec ivSpec = new IvParameterSpec(Base64Utils.decode(iv));
        // 初始化加密 设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        // 解密
        byte[] original = cipher.doFinal(Base64Utils.decode(encryptedData));
        // 去除补位字符
        byte[] bytes = PKCS7Encoder.decode(original);
        // 返回原文数据
        return new String(bytes);
    }
}
package cn.lettin.common.aes;

import java.util.ArrayList;

public class ByteGroup {
    ArrayList<Byte> byteContainer = new ArrayList<>();

    public byte[] toBytes() {
        byte[] bytes = new byte[byteContainer.size()];
        for (int i = 0; i < byteContainer.size(); i++) {
            bytes[i] = byteContainer.get(i);
        }
        return bytes;
    }

    public ByteGroup addBytes(byte[] bytes) {
        for (byte b : bytes) {
            byteContainer.add(b);
        }
        return this;
    }

    public int size() {
        return byteContainer.size();
    }
}
package cn.lettin.common.aes;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * PKCS#7填充算法
 * 提供基于PKCS7算法的加解密接口.
 */
public class PKCS7Encoder {
    static Charset CHARSET = StandardCharsets.UTF_8;
    static int BLOCK_SIZE = 32;

    /**
     * 获得对明文进行补位填充的字节.
     *
     * @param count 需要进行填充补位操作的明文字节个数
     * @return 补齐用的字节数组
     */
    public static byte[] encode(int count) {
        // 计算需要填充的位数
        int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
        if (amountToPad == 0) {
            amountToPad = BLOCK_SIZE;
        }
        // 获得补位所用的字符
        char padChr = chr(amountToPad);
        String tmp = new String();
        for (int index = 0; index < amountToPad; index++) {
            tmp += padChr;
        }
        return tmp.getBytes(CHARSET);
    }

    /**
     * 删除解密后明文的补位字符
     *
     * @param decrypted 解密后的明文
     * @return 删除补位字符后的明文
     */
    public static byte[] decode(byte[] decrypted) {
        int pad = (int) decrypted[decrypted.length - 1];
        if (pad < 1 || pad > 32) {
            pad = 0;
        }
        return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
    }

    /**
     * 将数字转化成ASCII码对应的字符,用于对明文进行补码
     *
     * @param a 需要转化的数字
     * @return 转化得到的字符
     */
    public static char chr(int a) {
        byte target = (byte) (a & 0xFF);
        return (char) target;
    }
}
  • Test
    @Test
    public void test3() throws Exception {
        String sessionKey = "UL2bN04+47AOM5L1/Fvm9A==";
        String encryptedData = "+nXMtl5NVHXIWiXaESesXk9h8+teKzFO/LDLbQaACLnBNJsxaKc8dX+FRxI6aoso7PwP4OaeGKiIHtlkkaKrx3WOdpqyN1Zhuq8Pd08JzJBXWasfzVXVnf8rdRvaz7T0bdX3Ci4E/kWAwGgejL9QIXJENyDBnEZOFr12rJxsFFtMwc1QR5rlFV9mKY6RxYU16pRR+3N+QbEU/4+JLPAun/8kdk5HPVzhiDclkbZTNa+qMzze88Ew1Ir/64G8PGAtyo7rojiUh4thioB/VSk0WWbBYa9BajdDqN8CJ/OIVUuIn/3JmrCnkvzmHmRZfTeU9t/+D4HN64m9As0h53D7kcyRQwQ2dkawCFJqDvLQvZ02bxE9cjHERGHtxacRnQ5rdXKku2zDiZTLbnNv1PAsiiJ/Hcr2tFXKrAyN4pS0cOc=";
        String iv = "8Xp9zfn6NrwTINgRKKyoXw==";
        String decrypt = AesUtils.decrypt(sessionKey, encryptedData, iv);
        System.out.println("解密结果  " + decrypt);
        String encrypt = AesUtils.encrypt(sessionKey, decrypt, iv);
        System.out.println("加密结果  " + encrypt);
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,可以使用AES/CBC/PKCS7Padding加密方法来对数据进行加密和解密操作。AES是Advanced Encryption Standard的缩写,是一种常用的对称加密算法CBC是Cipher Block Chaining的缩写,是一种使用前一块密文作为下一块的加密输入的模式。PKCS7Padding是一种填充方式,用于将数据填充到指定块的长度。 要使用AES/CBC/PKCS7Padding加密方法,首先需要选择一个合适的密钥和偏移量。密钥是用于加密和解密数据的关键,偏移量是用于初始化加密器的参数。同时,还需要选择一个合适的填充方式。 在Java中,可以使用JCE(Java Cryptography Extension)库来实现AES/CBC/PKCS7Padding加密方法。可以通过以下步骤进行加密和解密操作: 1. 生成AES密钥:可以使用KeyGenerator类来生成AES密钥。 2. 初始化Cipher对象:可以使用Cipher类来进行加密和解密操作。需要指定使用AES算法CBC模式,并设置填充方式为PKCS7Padding。 3. 初始化加密器参数:需要使用IvParameterSpec类来初始化加密器的偏移量参数。 4. 设置加密模式和密钥:需要使用Cipher的init方法来设置加密模式(加密或解密)和密钥。 5. 执行加密或解密操作:使用Cipher的doFinal方法来执行加密或解密操作。 使用Java中的AES/CBC/PKCS7Padding加密方法,可以对数据进行安全可靠的加密和解密。但是需要注意保护好密钥的安全性,以免被恶意使用者获取。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值