首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java AES解密BadPaddingException

Java AES解密BadPaddingException
EN

Stack Overflow用户
提问于 2013-06-25 06:14:30
回答 2查看 5.5K关注 0票数 2

注意: Java NOOB。

好吧,我知道这个问题在这里已经回答了几十次,但这些解决方案似乎不起作用/直接适用于我所理解的地方。(是的,我知道我不完全理解加密/解密、AES等,但这不是重点,我正在努力理解这一点)

我有一个实用程序api,我想在其中传递一个字符串并返回一个加密字符串。然后,我想传递加密的字符串,并返回一个解密的字符串。很简单。对于我传入的许多字符串,它都工作得很好,但在某些情况下,我得到了异常javax.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= =异常

下面是我的控制器中的代码:

代码语言:javascript
复制
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"),但在解密时总是失败。我很想真正了解这里发生了什么,以及如何修复它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-25 06:40:49

使用函数encodeBase64URLSafeString。javadoc说

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

这应该可以解决问题。

票数 3
EN

Stack Overflow用户

发布于 2013-06-25 06:28:09

因为这个类直接操作字节流,而不是字符流,所以它是硬编码的,只编码/解码与较低的127ASCII表(-8859-1、Windows-1252、UTF-8等)兼容的字符编码。

与byte[]/string之间的转换不会保留所有数据。密文的文本表示实际上并不是必需的,那么为什么要转换为字符串呢?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17286045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档