AES加密 CBC模式 PKCS7Padding填充 base64编码 密钥32byte iv16byte

本文介绍了一个使用AES128算法在CBC模式下进行加密和解密的Java实现。通过示例代码展示了如何使用BouncyCastle组件实现PKCS7Padding填充模式,以及如何初始化密钥和向量,完成数据的加密与解密过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.Arrays;


public class AES {



    public static void main(String[] args) throws IOException {
        AES aes = new AES();
        // 加解密 密钥
//        String key = "1234567890qwertyuiopasdfghjklzxc";
//        b'\x87\xe9\x11\xfe\x82\xce\x8dS\x08;9\xd2\xbfx\x03\x95\x15\x99\xc2\x02\x9c\xcb\xaa\xd7G\x16\xd8\xae\x157U\xdb'

        byte[] keybytes = {(byte)0x87,(byte)0xe9,(byte)0x11,(byte)0xfe,(byte)0x82,(byte)0xce,(byte)0x8d,'S',(byte)0x08,';','9',(byte)0xd2,(byte)0xbf,'x',(byte)0x03,(byte)0x95,(byte)0x15,(byte)0x99,(byte)0xc2,(byte)0x02,(byte)0x9c,(byte)0xcb,(byte)0xaa,(byte)0xd7,'G',(byte)0x16,(byte)0xd8,(byte)0xae,(byte)0x15,'7','U',(byte)0xdb};
//         byte[] keybytes = { '1','2','3','4','5','6','7','8','9','0','q','w','e','r','t','y','u','i','o','p','a','s','d','f','g','h','j','k','l','z','x','c' };
//        byte[] keybytes = key.getBytes();
        byte[] iv = {(byte)0x87,(byte)0xe9,(byte)0x11,(byte)0xfe,(byte)0x82,(byte)0xce,(byte)0x8d,'S',(byte)0x08,';','9',(byte)0xd2,(byte)0xbf,'x',(byte)0x03,(byte)0x95};

        //加密字符串
        String content = "Hello, 韩- 梅 -梅";
        System.out.println("加密前的:" + content);
        System.out.println("加密密钥:" + new String(keybytes));
        // 加密方法
        String enc = aes.encrypt(content.getBytes(), keybytes,iv);
//        String encode = new BASE64Encoder().encode(enc);
        System.out.println("加密后的内容:" + enc);
//        System.out.println("加密后的内容:" + new String(Hex.encode(enc)));

        // 解密方法
//        byte[] bytes = new BASE64Decoder().decodeBuffer(enc);
        String dec = aes.decrypt(enc, keybytes,iv);
        System.out.println("解密后的内容:" + new String(dec));
    }




    /**
     *
     * @author ngh
     *
     * AES128 算法
     *
     * CBC 模式
     *
     * PKCS7Padding 填充模式
     *
     * CBC模式需要添加一个参数iv
     *
     * 介于java 不支持PKCS7Padding,只支持PKCS5Padding 但是PKCS7Padding 和 PKCS5Padding 没有什么区别
     * 要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现
     */

    // 算法名称
    final String KEY_ALGORITHM = "AES";
    // 加解密算法/模式/填充方式
    final String algorithmStr = "AES/CBC/PKCS7Padding";
    //
    private Key key;
    private Cipher cipher;
    boolean isInited = false;

    //    String ivs = "1234567890qwerty";
//    byte[] iv = ivs.getBytes();
//    byte[] iv = {'1','2','3','4','5','6','7','8','9','0', 'q', 'w', 'e', 'r', 't', 'y' };
    public void init(byte[] keyBytes) {

        // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
        int base = 16;
        if (keyBytes.length % base != 0) {
            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
            keyBytes = temp;
        }
        // 初始化
        Security.addProvider(new BouncyCastleProvider());
        // 转化成JAVA的密钥格式
        key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
        try {
            // 初始化cipher
            cipher = Cipher.getInstance(algorithmStr, "BC");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * 加密方法
     *
     * @param content
     *            要加密的字符串
     * @param keyBytes
     *            加密密钥
     * @return
     */
    public String encrypt(byte[] content, byte[] keyBytes,byte[] iv) {
        byte[] encryptedText = null;
        init(keyBytes);
        System.out.println("IV:" + new String(iv));
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
            encryptedText = cipher.doFinal(content);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String encode = new BASE64Encoder().encode(encryptedText);
        return encode;
    }
    /**
     * 解密方法
     *
     *
     *            要解密的字符串
     * @param keyBytes
     *            解密密钥
     * @return
     */
    public String decrypt(String enc, byte[] keyBytes,byte[] iv) throws IOException {
        byte[] encryptedData = new BASE64Decoder().decodeBuffer(enc);
        byte[] encryptedText = null;
        init(keyBytes);
        System.out.println("IV:" + new String(iv));
        try {
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
            encryptedText = cipher.doFinal(encryptedData);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
//        String encode = new BASE64Encoder().encode(encryptedText);
        String str = new String(encryptedText);
        return str;


    }

}

 

<think>好的,用户需要关于Java中使用AES/CBC/PKCS5Padding加密的伪代码实现。首先,我得回忆一下AES加密的基本步骤。AES有不同的工作模式CBC是其中之一,而PKCS5Padding填充方式。需要确认Java中对应的实现类和方法。 首先,生成密钥的部分。AES密钥通常是通过KeyGenerator生成的,然后转换成SecretKey。不过用户可能需要密钥的存储,所以可能需要用密钥规范来生成,比如使用SecretKeySpec和一个固定的密钥。但要注意,硬编码密钥不安全,实际应用中应该从安全的地方获取。 接下来是初始化向量(IV)。CBC模式需要IV,而且每次加密应该使用不同的IV来增强安全性。通常IV是随机生成的,并且需要和密文一起存储,因为解密时需要同样的IV。在Java中,可以使用SecureRandom生成IV,然后通过IvParameterSpec来应用它。 然后是加密过程的步骤。初始化Cipher实例,设置为加密模式,指定算法为AES/CBC/PKCS5Padding。然后调用doFinal方法处理数据。这里要注意输入应该是字节数组,输出也是字节数组,然后通常会将IV和密文一起编码,比如用Base64方便传输或存储。 解密过程类似,不过需要从密文中提取IV。通常IV会放在密文前面,所以解密时需要先读取IV部分,再处理后面的密文数据。同样使用Cipher实例,但设置为解密模式,并传入正确的IV参数。 然后需要考虑异常处理,比如InvalidKeyException、NoSuchAlgorithmException等,这些在伪代码中可能不需要详细写出,但实际代码中必须处理。此外,密钥长度是否符合AES的要求,比如128、192或256位,需要确保密钥正确。 用户可能还关心伪代码的结构是否清晰,是否包含关键步骤。比如密钥生成、IV生成、加密和解密的流程。可能还需要提到PKCS5Padding的作用,以及CBC模式的特点,比如需要IV,分组链接等。 另外,引用部分提到了WebLogic中的加密字符串以{AES}开头,这可能意味着在实际应用中,密钥管理或存储的方式,但用户的问题主要是伪代码实现,所以这部分可能不需要深入,除非用户有进一步的疑问。 最后,生成相关问题时要围绕AES加密的实现细节、模式选择、填充方式、密钥管理等方面,帮助用户深入理解相关主题。</think>以下是用Java实现AES/CBC/PKCS5Padding加密的伪代码框架,包含关键步骤说明: ```java // 生成密钥(需替换为实际密钥) SecretKeySpec secretKey = new SecretKeySpec( decodeBase64("your-base64-encoded-key"), "AES" ); // 生成初始化向量(IVbyte[] ivBytes = new byte[16]; SecureRandom random = new SecureRandom(); random.nextBytes(ivBytes); IvParameterSpec iv = new IvParameterSpec(ivBytes); // 加密流程 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); // 组合IV和密文(IV需随密文传输) byte[] finalData = new byte[ivBytes.length + encryptedBytes.length]; System.arraycopy(ivBytes, 0, finalData, 0, ivBytes.length); System.arraycopy(encryptedBytes, 0, finalData, ivBytes.length, encryptedBytes.length); String result = Base64.getEncoder().encodeToString(finalData); ``` ```java // 解密流程(接收端) byte[] decoded = Base64.getDecoder().decode(encryptedString); byte[] receivedIv = Arrays.copyOfRange(decoded, 0, 16); byte[] ciphertext = Arrays.copyOfRange(decoded, 16, decoded.length); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(receivedIv)); byte[] decryptedBytes = cipher.doFinal(ciphertext); String plaintext = new String(decryptedBytes, StandardCharsets.UTF_8); ``` 关键点说明: 1. CBC模式需要唯一初始化向量(IV),建议每次加密生成新IV[^1] 2. PKCS5Padding自动处理数据块对齐 3. 必须安全存储密钥,硬编码密钥存在安全隐患 4. IV需要与密文一起存储/传输
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值