javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with pad

2023-11-05

今天在做AES加密时,项目中出现javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher异常是AES加密解密的报错异常,在向方法传输参数进行解密的过程中会报错,这个错误的字面意思就是java 使用AES解密报这个异常,字面理解很容易,就是解密的字符串的数组必须是16的倍数。

AESUtils 工具类:

package ctd.util.codec;

import com.fasterxml.jackson.databind.ObjectMapper;
import ctd.util.JSONUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;

public class AESUtils {

    private static final String KEY_ALGORITHM = "AES";
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    public static byte[] initSecretKey() throws Exception {
        KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
        kg.init(128);
        SecretKey secretKey = kg.generateKey();

        return secretKey.getEncoded();
    }

    public static String generatorSecretKey() throws Exception {
        return DigestUtils.md5Hex(initSecretKey()).substring(8, 24);
    }

    public static Key toKey(byte[] key) {
        return new SecretKeySpec(key, KEY_ALGORITHM);
    }

    public static String encrypt(String data, String key) throws Exception {
        return Base64.encodeBase64String(encrypt(data.getBytes(), toKey(key.getBytes()), DEFAULT_CIPHER_ALGORITHM));
    }

    public static String decrypt(String data, String key) throws Exception {
        return new String(decrypt(Base64.decodeBase64(data.getBytes()), toKey(key.getBytes()), DEFAULT_CIPHER_ALGORITHM));
    }

    public static byte[] encrypt(byte[] data, Key key) throws Exception {
        return encrypt(data, key, DEFAULT_CIPHER_ALGORITHM);
    }

    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        return encrypt(data, toKey(key), DEFAULT_CIPHER_ALGORITHM);
    }

    public static byte[] encrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception {
        Cipher cipher = Cipher.getInstance(cipherAlgorithm);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(data);
    }

    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        return decrypt(data, key, DEFAULT_CIPHER_ALGORITHM);
    }

    public static byte[] decrypt(byte[] data, Key key) throws Exception {
        return decrypt(data, key, DEFAULT_CIPHER_ALGORITHM);
    }

    public static byte[] decrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception {
        Key k = toKey(key);
        return decrypt(data, k, cipherAlgorithm);
    }

    public static byte[] decrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception {
        Cipher cipher = Cipher.getInstance(cipherAlgorithm);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(data);
    }

    private static String showByteArray(byte[] data) {
        if (null == data) {
            return null;
        }
        StringBuilder sb = new StringBuilder("{");
        for (byte b : data) {
            sb.append(b).append(",");
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.append("}");
        return sb.toString();
    }


    public static void main(String[] args) throws Exception {
        String key = generatorSecretKey();
        System.out.println("key: " + key);
        String[] original = new String[]{"hello 我是中文 world!"};
        try {
            String encrypt = encrypt(new ObjectMapper().writeValueAsString(original), key);
            System.out.println("encrypt: " + encrypt);
            String decrypt = decrypt(encrypt, key);
            System.out.println("decrypt: " + decrypt);
            System.out.println("original: " + JSONUtils.parse(decrypt.getBytes(), String[].class));
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }
}

调用:

                        String enc = AESUtils.decrypt(IOUtils.toString(request.getInputStream()), aes128_encrypt_key);

报错原因:

一步步的调试,我们可以看到哦,我们能够看到参数的传递到后台我们的参数中是否包含处参数以外的其他字符,否则就会报错。

解决方案:

将传递的参数的其他字符想办法去除。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with pad 的相关文章

随机推荐

  • Zotero文献导入到Endnote

    1 2 导入的时候 请选择
  • STM32 DAC + DMA + TIM 输出正弦波,三角波,方波信号

    硬件平台 STM32F4 库类型 标准库 参考 二代示波器教程 第12章 示波器设计 DAC信号发生器的实现 DAC框图如下 通过TIM触发DAC转换 转换完成后通过DMA输出 DMA通道框图 DAC输出阻抗的问题 DAC集成了2个输出缓存
  • matlab练习程序(弧形、圆柱投影的复原)

    前一段介绍了从矩形图像到圆柱的正向投影 看这里和这里 今天介绍如何从已经投影的图像反映射到原图像上 本来此种变换一定是需要数学公式的 不过这里只是用了一个很简单的方式来完成反映射 具体就把每一列有像素数据的长度拉伸到原图像的高就行了 原图像
  • html网页超链接

    HTML网页超链接可以通过a标签来添加超链接 其语法是 a href target self title a 它的两个属性值分别是href用来设置网页目标地址 target是用来设置打开超链接的方式 a href 网址 链接地址 targe
  • 字体子集化fontmin应用

    const fm require fontmin const f 字体名称 ttf const fontmin new fm fontmin src f use fm glyph text 天地玄黄 宇宙洪荒 use fm ttf2svg
  • 二、图像二值化方法(python)---阈值全局固定、大津法

    文章目录 阈值全局固定 利用python实现阈值全局固定时的二值化 效果图 大津法OTSU 利用Python实现大津法 效果图如下 图像二值化也叫做图像阈值化处理 通过设定某个阈值为门限 把多灰度级的图像转化为仅仅有两个极端的灰度级 0和2
  • C/C++编程笔记:如何将字符串转换为数字,数字转换为字符串?

    通常 或更具体地说 在竞争性编程中 有许多情况需要将数字转换为字符串或将字符串转换为数字 但是缺乏某些必不可少的工具的知识使我们不得不这样做 本文介绍了一些实现此任务的方法 将字符串转换为数字 方法1 使用stringstream类或ssc
  • 【转】探索推荐引擎内部的秘密

    from http www ibm com developerworks cn web 1103 zhaoct recommstudy1 index html ca drs 赵 晨婷 软件工程师 IBM 马 春娥 软件工程师 IBM 简介
  • 基于API调用管理的SDN应用层DDoS攻击防御机制

    摘要 软件定义网络 SDN software defined network 针对北向接口安全研究少 加之缺乏严格的访问控制 身份认证及异常调用检测等机制 导致攻击者有机会开发恶意的应用程序 造成北向应用程序接口 API applicati
  • Ubuntu中最简单好用截图工具shutter安装

    题记 在ubuntu中 shutter截图工具是我目前使用过最简单好用的截图神器 安装 直接在ubuntu软件市场中搜索下载 然后安装即可了
  • 软件测试工程师必备的10个测试技术体系(零基础入行测试必学)

    很多测试新手在刚开始学习软件测试的时候都不知道该如何开始 以及软件测试需要掌握哪些必备的知识点 以下是根据个人总结 粗略整理的一份软件测试学习大纲 基本涵盖了软件测试工程师需要掌握的全部技能 希望给准备学习测试的朋友提供一点指引和帮助 PS
  • 八大排序算法-堆排序

    在说堆排序之前 要先说明二叉堆的概念 因为堆排序就是通过二叉堆来实现的 注 以下说会用堆来作二叉堆的简称 至于堆的定义 大家可以自行查阅 在了解完堆之后 我们知道堆有大根堆和小根堆的不同 我们先了解堆排序的思想 之后用一个大根堆来实现代码
  • 搜索引擎-应用篇(地理位置查询)

    一 背景 查询附近的洗车店 二 原理探究 像Redis和ES都支持GEO来存储地理位置 GEO类型 地理点 geo point 即经纬度查询 地理形状查询 geo shape 即支持点 线 圈 多边形查询 GeoHash GeoHash 原
  • 转:图谱中的关系推理是什么

    知识图谱本质上是语义网络 是一种基于图的数据结构 由节点 Point 实体 和边 Edge 关系 组成 在知识图谱里 每个节点表示现实世界中存在的 实体 每条边为实体与实体之间的 关系 知识图谱是关系的最有效的表示方式 通俗地讲 知识图谱就
  • Win10企业版本激活方法

    右键管理员身份运行cmd 或者直接Win键 X 直接打开Windows Powershell 管理员 粘贴下面的命令即可 slmgr skms kms 03k org slmgr ato
  • scrollIntoView()的方法属性及使用其实现锚点定位

    scrollIntoView 方法属性 在一个移动项目中遇到个这样的需求 一个表单填写页面 每项都有表单验证 并且点击提交按钮 未通过校验的输入框下边显示校验信息 同时页面滑动定位到第一个未通过校验的输入框 我们在完成这项需求时 使用的sc
  • GROUP BY 与 HAVING

    sql语句中GROUP BY 和 HAVING的使用 count http blog 163 com hks blog blog static 214926090201382225845920 ql中的group by 和 having 用
  • swagger 接口测试,用 python 写自动化时该如何处理?

    在使用Python进行Swagger接口测试时 可以使用requests库来发送HTTP请求 并使用json库和yaml库来处理响应数据 以下是一个简单的示例代码 import requests import json import yam
  • 排序算法性能分析

    目录 实现插入排序 冒泡排序 选择排序 合并排序 快速排序算法 从小到大 插入排序 冒泡排序 选择排序 快速排序 五种排序 现在有10亿的数据 每个数据四个字节 请快速挑选出最大的十个数 并在小规模数据上验证算法的正确性 方法一 规模为10
  • javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with pad

    今天在做AES加密时 项目中出现javax crypto IllegalBlockSizeException Input length must be multiple of 16 when decrypting with padded c