简体   繁体   English

Java AES解密BadPaddingException

[英]Java AES decryption BadPaddingException

note: Java NOOB. 注意:Java NOOB。

Alright, I know this has been answered a few dozen times on here, but the solutions don't seem to work/apply directly to where I understand them. 好吧,我知道这里已经回答了几十次,但是这些解决方案似乎并不能直接应用于我理解的地方。 (Yes, I know I don't completely understand encryption/decryption, AES, etc. but that is not the point, I am trying to understand this) (是的,我知道我不完全了解加密/解密,AES等,但这不是重点,我试图理解这一点)

I have a utility api where I want to pass a string and return an encrypted string. 我有一个实用程序api,我想在其中传递一个字符串并返回一个加密的字符串。 Then I want to pass the encrypted string, and return a decrypted string. 然后,我想传递加密的字符串,并返回解密的字符串。 Simple. 简单。 It works fine for many strings I pass in, but on some, I'm getting the exception javax.crypto.BadPaddingException: Given final block not properly padded. 它对于我传入的许多字符串都可以正常工作,但是在某些情况下,我却收到异常javax.crypto.BadPaddingException: Given final block not properly padded.

For example, the following encrypts/decrypts fine. 例如,以下加密/解密很好。
util/encrypt/?token=123456789012wha = 4TR0CbCcQKqeRK73zr83aw== util/encrypt/?token=123456789012wha = 4TR0CbCcQKqeRK73zr83aw ==
util/decrypt/?token=4TR0CbCcQKqeRK73zr83aw== = 123456789012wha util/decrypt/?token=4TR0CbCcQKqeRK73zr83aw== = 123456789012wha

The following encrypts, but does not decrypt: 以下加密,但不解密:
util/encrypt/?token=123456789012what = NYaWmwnySoGNHyNmY9Jh+f3O2rqoLI1IAcnsl5V4OCE= util/encrypt/?token=123456789012what = NYaWmwnySoGNHyNmY9Jh + f3O2rqoLI1IAcnsl5V4OCE =
util/decrypt/?token=NYaWmwnySoGNHyNmY9Jh+f3O2rqoLI1IAcnsl5V4OCE= = exception util/decrypt/?token=NYaWmwnySoGNHyNmY9Jh+f3O2rqoLI1IAcnsl5V4OCE= =异常

Here is the code in my controller: 这是我的控制器中的代码:

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;
}

I figure it must be something with the call Cipher.getInstance() and I've tried using Cipher.getInstance("AES/CBC/PKCS5Padding") but that always fails when decrypting. 我认为这一定是通过调用Cipher.getInstance()并且我尝试使用Cipher.getInstance("AES/CBC/PKCS5Padding")但是解密时总是失败。 I would love to really understand what is happening here and how to fix it. 我很想真正了解这里发生的事情以及如何解决它。

Use the function encodeBase64URLSafeString . 使用函数encodeBase64URLSafeString the javadoc says Javadoc说

Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. 使用base64算法的URL安全变体对二进制数据进行编码,但不对输出进行分块。 The url-safe variation emits - and _ instead of + and / characters. 网址安全变体发出-和_而不是+和/字符。 Note: no padding is added. 注意:未添加填充。

This should solve the problem. 这应该可以解决问题。

Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc). 由于此类直接在字节流而不是字符流上运行,因此它被硬编码为仅编码/解码与较低的127个ASCII图表兼容的字符编码(ISO-8859-1,Windows-1252,UTF-8,等等)。

Your conversion to/from byte[]/string does not preserve all the data. 您与byte [] / string之间的转换不会保留所有数据。 Textual representation of the ciphertext isn't really necessary so why are you converting to a string? 密文的文本表示形式实际上不是必需的,那么为什么要转换为字符串?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM