Base64加密解密不一致导致AES加密报出javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 wh
Posted whalesea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Base64加密解密不一致导致AES加密报出javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 wh相关的知识,希望对你有一定的参考价值。
报错的意思的是使用该种解密方式出入长度应为16bit的倍数,但实际的错误却不是这个,错误原因根本上是因为在http请求是特殊字符编码错误,具体数就是base64生成的+号,服务器接收时成了空格,然后导致base64解码出的字节数组有改变。
下面来还原并分析一下具体原因:
请求代码:
@Test public void testHttp() throws Exception //16进制字节数组,单纯的为了生成含有+的base64位字符串,是在试了好多遍都没试到+,只能把我错误例子的byte数组转成16进制,为我的机智点个赞 String src = "34aa8bc0adaccbe45ac8c7e43d25955f4d3b51a189339af3d5b968b49764f4def4b81ab285a461504a5cb930c08055f96e875e2b4be390f6708ae686b13e8ff3bed9e9455c638c3809e4c51db05ac3f496be28772829270998eddb9ec6c08c4a0cc1d23e59c6ebe8b73b75013ba9eee5"; byte[] bytes = Hex.decodeHex(src); String base64Str = Base64.encodeBase64String(bytes); System.out.println("发送时的字符串:"+base64Str); for(int i=0;i<bytes.length;i++) System.out.println(bytes[i]); String httpUrl = "http://10.20.20.184:10086/dbzx/hello?src="+base64Str; HttpRequest.doGet(httpUrl);
打印结果:
发送时的字符串:NKqLwK2sy+RayMfkPSWVX007UaGJM5rz1blotJdk9N70uBqyhaRhUEpcuTDAgFX5bodeK0vjkPZwiuaGsT6P877Z6UVcY4w4CeTFHbBaw/SWvih3KCknCZjt257GwIxKDMHSPlnG6+i3O3UBO6nu5Q== 52 -86 -117 -64 -83 -84 -53 -28 90 -56 -57 -28 61 37 -107 95 77 59 81 -95 -119 51 -102 -13 -43 -71 104 -76 -105 100 -12 -34 -12 -72 26 -78 -123 -92 97 80 74 92 -71 48 -64 -128 85 -7 110 -121 94 43 75 -29 -112 -10 112 -118 -26 -122 -79 62 -113 -13 -66 -39 -23 69 92 99 -116 56 9 -28 -59 29 -80 90 -61 -12 -106 -66 40 119 40 41 39 9 -104 -19 -37 -98 -58 -64 -116 74 12 -63 -46 62 89 -58 -21 -24 -73 59 117 1 59 -87 -18 -27
服务端代码:
package com.dbzx.controller; import org.apache.commons.codec.binary.Base64; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.dbzx.common.ResultModel; @RestController @RequestMapping("dbzx") public class HelloController @RequestMapping("/hello") public ResultModel hello(String src) System.out.println("接收到的字符串:"+src); byte[] bytes = Base64.decodeBase64(src); for(int i=0;i<bytes.length;i++) System.out.println(bytes[i]); return ResultModel.ok();
打印结果:
接收到的字符串:NKqLwK2sy RayMfkPSWVX007UaGJM5rz1blotJdk9N70uBqyhaRhUEpcuTDAgFX5bodeK0vjkPZwiuaGsT6P877Z6UVcY4w4CeTFHbBaw/SWvih3KCknCZjt257GwIxKDMHSPlnG6 i3O3UBO6nu5Q== 52 -86 -117 -64 -83 -84 -55 22 -78 49 -7 15 73 101 87 -45 78 -44 104 98 76 -26 -68 -11 110 90 45 37 -39 61 55 -67 46 6 -84 -95 105 24 84 18 -105 46 76 48 32 21 126 91 -95 -41 -118 -46 -8 -28 61 -100 34 -71 -95 -84 79 -93 -4 -17 -74 122 81 87 24 -29 14 2 121 49 71 108 22 -80 -3 37 -81 -118 29 -54 10 73 -62 102 59 118 -25 -79 -80 35 18 -125 48 116 -113 -106 113 -70 -117 115 -73 80 19 -70 -98 -18 80
通过两端的结果对比可以发现发送前是+,服务器接收的是空格,这是因为有些特殊字符在http请求时是无法编码的,其实base64就是解决类似问题得,只是越来越多的特殊字符,导致它出错。
有些人说base64会把+和空格转成相同的字节码,不会出错,但是我们来对比一下字节码。
可以看到,在第7行是报错。
而原本字符串(NKqLwK2sy+)+在第10个位置,跟据base64的规则,4个base64转成的字符串,代表3个原本的字符串,而上图第七个字节,需要"y+"共同构造,这就是出错的原因。既是aes解码出错的原因。
至于16的倍数,理论上只用是偶数位的字节数都满足,显示错误出在其他方面,这个例子就是字节码出错了。
以上是关于Base64加密解密不一致导致AES加密报出javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 wh的主要内容,如果未能解决你的问题,请参考以下文章