AES解密

本文介绍了一个AES算法工具类,该工具类使用CBC模式和PKCS7填充方式实现数据的加密和解密。提供了两种方法来获取Cipher实例,并通过示例展示了如何使用这些方法进行AES解密。

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

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.util.Base64;

/**
 * AES算法工具类
 */
public class AESUtil {

    private final static Logger logger = LoggerFactory.getLogger(AESUtil.class);

    /**
     * 密码算法
     */
    private final static String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
    /**
     * Key算法
     */
    private final static String KEY_ALGORITHM = "AES";

    /**
     * 密码
     */
    private static ThreadLocal<Cipher> cipherThreadLocal = new ThreadLocal<>();
    private static ThreadLocal<Cipher> cipherBCThreadLocal = new ThreadLocal<>();

//    static {
//        Security.addProvider(new BouncyCastleProvider());
//        try {
//            cipher = Cipher.getInstance(CIPHER_ALGORITHM);
//        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
//            logger.error("AESUtil produce cipher error.", e);
//            cipher = null;
//        }
//    }

    public static Cipher getCipher() {
        Security.addProvider(new BouncyCastleProvider());
        try {
            if (cipherThreadLocal.get() == null) {
                Cipher c = Cipher.getInstance(CIPHER_ALGORITHM);
                cipherThreadLocal.set(c);
            }
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            logger.error("AESUtil produce cipher error.", e);
            cipherThreadLocal = null;
        }
        return cipherThreadLocal.get();
    }

    /**
     * AES解密
     *
     * @param encryptedData 加密数据
     * @param encodeKey Base64编码的Key
     * @param encodeIv  Base64编码的偏移量
     * @return  解密后的数据
     */
    public static String decrypt(String encryptedData, String encodeKey, String encodeIv) {
        Cipher cipher = getCipher();
        if (cipher == null) {
            return null;
        }
        byte[] decodeData = decodeData(encryptedData);
        SecretKeySpec secretKey = decodeKey(encodeKey);
        IvParameterSpec ivParameter = decodeIv(encodeIv);

        try {
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameter);
            return new String(cipher.doFinal(decodeData));
        } catch (InvalidKeyException
                | InvalidAlgorithmParameterException
                | IllegalBlockSizeException
                | BadPaddingException e) {
            logger.error("AESUtil decrypt data error. openId:{}, e:{}", e);
            return null;
        }
    }


    public static Cipher getCipherBC() {
        Security.addProvider(new BouncyCastleProvider());
        try {
            if (cipherBCThreadLocal.get() == null) {
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
                cipherBCThreadLocal.set(cipher);
            }
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException e) {
            logger.error("AESUtil produce cipher error.", e);
            cipherBCThreadLocal = null;
        }
        return cipherBCThreadLocal.get();
    }

    /**
     * AES解密
     *
     * @param encryptedData 加密数据
     * @param encodeKey Base64编码的Key
     * @param encodeIv  Base64编码的偏移量
     * @return  解密后的数据
     */
    public static String decryptBC(String encryptedData, String encodeKey, String encodeIv) {
        Cipher cipher = getCipherBC();
        if (cipher == null) {
            return null;
        }
        byte[] decodeData = decodeData(encryptedData);
        SecretKeySpec secretKey = decodeKey(encodeKey);
        IvParameterSpec ivParameter = decodeIv(encodeIv);

        try {
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameter);
            return new String(cipher.doFinal(decodeData));
        } catch (InvalidKeyException
                | InvalidAlgorithmParameterException
                | IllegalBlockSizeException
                | BadPaddingException e) {
            logger.error("AESUtil decrypt data error. openId:{}, e:{}", e);
            return null;
        }
    }

    /**
     * 解码数据
     *
     * @param encodeData  编码数据
     * @return  数据
     */
    private static byte[] decodeData(String encodeData) {
        return Base64.getDecoder().decode(encodeData);
    }

    /**
     * 解码Key
     *
     * @param encodeKey  编码Key
     * @return  Key
     */
    private static SecretKeySpec decodeKey(String encodeKey) {
        byte[] decodeKey = Base64.getDecoder().decode(encodeKey);
        return new SecretKeySpec(decodeKey, KEY_ALGORITHM);
    }

    /**
     * 解码偏移量
     *
     * @param encodeIv  编码偏移量
     * @return  偏移量
     */
    private static IvParameterSpec decodeIv(String encodeIv) {
        byte[] decodeIv = Base64.getDecoder().decode(encodeIv);
        return new IvParameterSpec(decodeIv);
    }
}
### AES解密方法概述 AES(Advanced Encryption Standard),即高级加密标准,是一种对称加密算法,在现代密码学中被广泛应用。它通过特定的密钥对数据进行加解密操作,确保数据的安全性和保密性。以下是关于AES解密的具体实现方法及其代码示例。 --- #### Java 中的 AES 解密实现 在Java中,可以通过`javax.crypto.Cipher`类来完成AES解密的操作。下面是一个完整的Java AES解密示例: ```java import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class AesDecryptExample { private static final String ALGORITHM = "AES"; private static final String TRANSFORMATION = "AES"; public static String decrypt(String encryptedData, String key) throws Exception { SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM); Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] decodedBytes = Base64.getDecoder().decode(encryptedData); byte[] decryptedBytes = cipher.doFinal(decodedBytes); return new String(decryptedBytes); } public static void main(String[] args) { try { String encryptedText = "your_encrypted_data_here"; // 替换为实际的加密数据 String secretKey = "1234567890abcdef"; // 密钥长度需满足AES要求 (16, 24, 或 32 字节) String decryptedText = decrypt(encryptedText, secretKey); System.out.println("Decrypted Text: " + decryptedText); } catch (Exception e) { e.printStackTrace(); } } } ``` 上述代码展示了如何使用Java中的AES算法进行解密[^1]。需要注意的是,密钥长度应严格遵循AES的要求(128位、192位或256位)。 --- #### Python 中的 AES 解密实现 Python提供了多种库用于AES加密和解密操作,其中最常用的是`pycryptodome`库。以下是一个基于该库的AES解密示例: ```python from Crypto.Cipher import AES from Crypto.Util.Padding import unpad import base64 def aes_decrypt(ciphertext_base64, key, iv=None): ciphertext = base64.b64decode(ciphertext_base64) if iv is None: mode = AES.MODE_ECB cipher = AES.new(key.encode('utf-8'), mode) else: mode = AES.MODE_CBC cipher = AES.new(key.encode('utf-8'), mode, iv=iv.encode('utf-8')) plaintext_padded = cipher.decrypt(ciphertext) plaintext = unpad(plaintext_padded, AES.block_size).decode('utf-8') return plaintext if __name__ == "__main__": encrypted_text = "your_encrypted_data_here" # 替换为实际的Base64编码后的加密数据 decryption_key = "1234567890abcdef" # 密钥长度需满足AES要求 (16, 24, 或 32 字节) initialization_vector = "abcdef1234567890" # 如果使用CBC模式,则需要IV decrypted_text = aes_decrypt(encrypted_text, decryption_key, initialization_vector) print(f"Decrypted Text: {decrypted_text}") ``` 此代码片段实现了两种常见的AES解密模式:ECB 和 CBC[^3]。如果采用CBC模式,初始化向量(IV)是必需参数;而在ECB模式下则不需要。 --- #### Vue3 前端环境下的 AES 解密 对于Vue3项目而言,可以借助第三方库如`crypto-js`来轻松实现AES解密功能。以下是一段简单的示例代码: ```javascript import CryptoJS from 'crypto-js'; function aesDecrypt(encryptedData, key) { const bytes = CryptoJS.AES.decrypt(encryptedData.toString(), key.trim()); const originalText = bytes.toString(CryptoJS.enc.Utf8); return originalText; } // 使用示例 const encryptedText = "your_encrypted_data_here"; // 替换为实际的加密数据 const decryptionKey = "1234567890abcdef"; // 密钥长度需满足AES要求 (16, 24, 或 32 字节) try { const decryptedText = aesDecrypt(encryptedText, decryptionKey); console.log(`Decrypted Text: ${decryptedText}`); } catch (error) { console.error(error.message); } ``` 这段代码适用于前端环境中执行AES解密操作[^2]。注意,为了提高安全性,建议仅在必要时才将敏感逻辑暴露于客户端侧。 --- ### 总结 无论是在服务端还是客户端开发场景中,都可以找到适合的语言工具包来进行AES解密工作。重要的一点是要保证所使用的密钥符合AES的标准规格,并妥善保管这些秘密材料以免泄露风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值