Java AES解密BadPaddingException

注意:Java NOOB。

好吧,我知道这里已经回答了几十次,但解决方案似乎不能直接应用于我理解它们的地方。 (是的,我知道我不完全理解加密/解密,AES等等,但这不是重点,我试图理解这一点)

我有一个实用程序api,我想传递一个字符串并返回一个加密的字符串。 然后我想传递加密的字符串,并返回一个解密的字符串。 简单。 它适用于我传入的许多字符串,但在某些字符串上,我得到exceptionjavax.crypto.BadPaddingException: Given final block not properly padded.

例如,以下加密/解密很好。
util/encrypt/?token=123456789012wha = 4TR0CbCcQKqeRK73zr83aw ==
util/decrypt/?token=4TR0CbCcQKqeRK73zr83aw== = 123456789012wha

以下加密,但不解密:
util/encrypt/?token=123456789012what = NYaWmwnySoGNHyNmY9Jh + f3O2rqoLI1IAcnsl5V4OCE =
util/decrypt/?token=NYaWmwnySoGNHyNmY9Jh+f3O2rqoLI1IAcnsl5V4OCE= = exception

这是我的控制器中的代码:

 private static final String ALGO = "AES"; @RequestMapping(value = "/util/encrypt/", method = RequestMethod.GET) @ResponseBody public String encrypt(HttpServletResponse httpResponse, @RequestParam(value = "token", required=true) String token) throws Exception { Key key = generateKey(); Cipher c = Cipher.getInstance(ALGO); c.init(Cipher.ENCRYPT_MODE, key); byte[] encVal = c.doFinal(token.getBytes()); String encryptedValue = Base64.encodeBase64String(encVal); return encryptedValue.trim(); } @RequestMapping(value = "/util/decrypt/", method = RequestMethod.GET) @ResponseBody public String decrypt(HttpServletResponse httpResponse, @RequestParam(value = "token", required=true) String token) throws Exception { token = URLDecoder.decode(token, "UTF-8"); Key key = generateKey(); Cipher c = Cipher.getInstance(ALGO); c.init(Cipher.DECRYPT_MODE, key); byte[] decordedValue = Base64.decodeBase64(token); byte[] decValue = c.doFinal(decordedValue); String decryptedValue = new String(decValue); return decryptedValue.trim(); } private Key generateKey() throws Exception { Key key = new SecretKeySpec(getAesKey().getBytes(), ALGO); return key; } 

我认为它必须是调用Cipher.getInstance()东西,我尝试使用Cipher.getInstance("AES/CBC/PKCS5Padding")但在解密时总是失败。 我很想知道这里发生了什么以及如何解决它。

使用函数encodeBase64URLSafeString 。 javadoc说

使用base64算法的URL安全变体对二进制数据进行编码,但不会对输出进行分块。 url-safe变体发出 – 而_而不是+和/字符。 注意:不添加填充。

这应该可以解决问题。

由于这个类直接在字节流上运行,而不是在字符流上运行,因此硬编码只能编码/解码与低127 ASCII图表兼容的字符编码(ISO-8859-1,Windows-1252,UTF-8,等等)。

您对byte /] / string的转换不会保留所有数据。 密文的文本表示不是真的必要,那么为什么要转换为字符串呢?