AES加密算法(32位无偏移值)

4 篇文章 0 订阅

 一、AES工具类

@Slf4j
public class AesUtil {
    /**
     * 默认的字符编码
     */
    private static final String DEFAULT_CHARSET = "utf-8";

    /**
     * 算法
     */
    private static final String ALGORITHM = "AES";

    /**
     * 算法/模式/填充
     **/
    private static final String CipherMode = "AES/ECB/PKCS5Padding";

    /**
     * 密钥(32位)
     */
    public static final String key = "12345678123456781234567812345678";

    private AesUtil() {
    }

    /**
     * 解密AES 32位
     *
     * @param sSrc      解密的内容
     * @param secretKey 秘钥
     * @return 解密后的明文 数据
     */
    public static String decrypt(String sSrc, String secretKey) {
        if (secretKey == null) {
            log.error("需要加密的秘钥为空");
            return null;
        }
        try {
            byte[] raw = secretKey.getBytes(DEFAULT_CHARSET);
            SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            // 先用base64解密
            byte[] encryptedArr = Base64.getDecoder().decode(sSrc);
            byte[] original = cipher.doFinal(encryptedArr);
            return new String(original, DEFAULT_CHARSET);
        } catch (Exception ex) {
            log.error("AES解密失败", ex);
            return null;
        }
    }

    /**
     * 加密32位
     *
     * @param sSrc 需要加密的内容
     * @param sKey 秘钥
     * @return 加密的内容
     */
    public static String encrypt(String sSrc, String sKey) {

        if (sKey == null) {
            log.error("需要加密的秘钥为空");
            return null;
        }
        try {
            byte[] raw = sKey.getBytes(DEFAULT_CHARSET);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, ALGORITHM);
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            byte[] encrypted = cipher.doFinal(sSrc.getBytes(DEFAULT_CHARSET));

            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception ex) {
            log.error("AES加密失败", ex);
            return null;
        }
    }

    // 测试
    public static void main(String[] args) {
        // 明文
        String str = "你好!!!";
        // 加密
        String encrypt = encrypt(str, key);
        System.out.println(encrypt);
        // 解密
        String decrypt = decrypt(encrypt, key);
        System.err.println(decrypt);
    }
}

 二、异常问题(Illegal key size or default parameters)

        因为美国的出口限制,Sun通过权限文件(local_policy.jar、US_export_policy.jar)做了相应限制。因此存在以下一些问题:

        1.密钥长度上不能满足需求(如:java.security.InvalidKeyException: Illegal key size or default parameters);
        2.部分算法未能支持,如MD4、SHA-224等算法;
        3.API使用起来还不是很方便;
        4.一些常用的进制转换辅助工具未能提供,如Base64编码转换、十六进制编码转换等工具。

Exception in thread "main" java.lang.RuntimeException: Illegal key size or default parameters
	at com.cupdata.oam.cardapply.kit.AesKit.decrypt(AesKit.java:98)
	at com.cupdata.oam.cardapply.kit.AesKit.decrypt(AesKit.java:86)
	at com.cupdata.oam.cardapply.kit.AesKit.decryptToStr(AesKit.java:56)
	at com.cupdata.oam.cardapply.kit.AesKit.main(AesKit.java:194)
Caused by: java.security.InvalidKeyException: Illegal key size or default parameters
	at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1026)
	at javax.crypto.Cipher.implInit(Cipher.java:801)
	at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
	at javax.crypto.Cipher.init(Cipher.java:1249)
	at javax.crypto.Cipher.init(Cipher.java:1186)
	at com.cupdata.oam.cardapply.kit.AesKit.decrypt(AesKit.java:94)
	... 3 more

         如果在运行代码时出现以上错误,很可能时你的jdk版本过低,需要进行jdk升级,jdk到1.8.0_180或1.8.0_251或1.8.0_311版本以上都可以使用!!!

        也可以更换JCE的库,该文件位置在你的JDK/jre/lib/security 目录下面,该目录下我们可以看到两个jar包:local_policy.jarUS_export_policy.jar,这两个jar包是jdk自带的。我们需要下载支持256位密钥加密的jar包进行替换即可。

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在VS2015中实现AES加密并支持偏移量(IV)需要以下步骤: 1. 安装Cryptographic Services库 在VS2015中,需要安装CryptoAPI库才能使用加密API。可以通过在“控制面板”中选择“程序和功能”,然后选择“添加或删除Windows功能”来安装它。 2. 包含头文件和链接库 在程序中包含以下头文件: ``` #include <wincrypt.h> #pragma comment(lib, "crypt32.lib") ``` 3. 初始化加密操作 定义一个`HCRYPTPROV`类型的变量,用于表示加密服务提供程序的句柄。使用`CryptAcquireContext`函数初始化加密操作: ``` HCRYPTPROV hCryptProv; if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { // 初始化失败 } ``` 4. 生成随机偏移量 使用`CryptGenRandom`函数生成随机数作为偏移量: ``` BYTE iv[16]; if (!CryptGenRandom(hCryptProv, sizeof(iv), iv)) { // 生成随机数失败 } ``` 5. 设置加密算法 定义一个`HCRYPTKEY`类型的变量,用于表示加密密钥的句柄。使用`CryptCreateKey`函数创建加密密钥: ``` HCRYPTKEY hKey; if (!CryptCreateKey(hCryptProv, CALG_AES_128, 0, 0, &hKey)) { // 创建加密密钥失败 } ``` 6. 加密数据 使用`CryptEncrypt`函数加密数据: ``` BYTE dataToEncrypt[1024]; DWORD dataSize = sizeof(dataToEncrypt); // 填充数据 // ... if (!CryptEncrypt(hKey, 0, TRUE, 0, dataToEncrypt, &dataSize, sizeof(dataToEncrypt))) { // 加密数据失败 } ``` 其中,第二个参数为偏移量,第三个参数表示是否填充数据。 7. 解密数据 使用`CryptDecrypt`函数解密数据: ``` BYTE dataToDecrypt[1024]; DWORD dataSize = sizeof(dataToDecrypt); // 填充数据 // ... if (!CryptDecrypt(hKey, 0, TRUE, 0, dataToDecrypt, &dataSize)) { // 解密数据失败 } ``` 8. 释放资源 使用`CryptDestroyKey`和`CryptReleaseContext`函数释放资源: ``` CryptDestroyKey(hKey); CryptReleaseContext(hCryptProv, 0); ``` 以上就是在VS2015中实现AES加密并支持偏移量(IV)的步骤。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

i源

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值