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== 异常

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

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")但解密时总是失败。我很想真正了解这里发生了什么以及如何解决它。

4

2 回答 2

3

使用函数encodeBase64URLSafeString。javadoc说

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

这应该可以解决问题。

于 2013-06-24T22:40:49.430 回答
2

由于此类直接对字节流而不是字符流进行操作,因此它被硬编码为仅编码/解码与较低的 127 ASCII 图表(ISO-8859-1、Windows-1252、UTF-8、 ETC)。

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

于 2013-06-24T22:28:09.370 回答