java AES/CBC/PKCS5Padding 问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11065063/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 03:39:10  来源:igfitidea点击:

AES/CBC/PKCS5Padding issue

javacryptographyaesjce

提问by Sergey Mashkov

I am trying to encrypt and decrypt some simple text. But for some reason I am getting a strange error: javax.crypto.BadPaddingException. Why would JCE generates bytes that are not properly padded?

我正在尝试加密和解密一些简单的文本。但由于某种原因,我收到一个奇怪的错误:javax.crypto.BadPaddingException. 为什么 JCE 会生成未正确填充的字节?

I have the following code:

我有以下代码:

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;

public class SimplestTest {
    public static void main(String[] args) throws Exception {
        SecureRandom rnd = new SecureRandom();

        String text = "Hello, my dear! ... " + System.getProperty("user.home");
        byte[] textData = text.getBytes();

        IvParameterSpec iv = new IvParameterSpec(rnd.generateSeed(16));

        KeyGenerator generator = KeyGenerator.getInstance("AES");
        generator.init(128);
        SecretKey k = generator.generateKey();

        Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
        c.init(Cipher.ENCRYPT_MODE, k, iv);
        c.update(textData);
        byte[] data = c.doFinal();

        System.out.println("E: " + data.length);

        c = Cipher.getInstance("AES/CBC/PKCS5Padding");
        c.init(Cipher.DECRYPT_MODE, k, iv);
        c.update(data);

        System.out.println("R: " + c.doFinal().length);
    }

}

But for some reason it does not work. It fails with this exception:

但由于某种原因它不起作用。它因以下异常而失败:

E: 16
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
        at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
        at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
        at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
        at javax.crypto.Cipher.doFinal(DashoA13*..)
        at SimplestTest.main(SimplestTest.java:31)

What's going wrong? The data size is 16 bytes in length but is still "not properly padded" ?

怎么了?数据大小为 16 个字节,但仍然“未正确填充”?

回答by John Watts

Cipher.update returns a byte[] as well. So you are missing part of the encrypted data when you go to decrypt. Update the last section to read as follows:

Cipher.update 也返回一个 byte[]。因此,当您进行解密时,您会丢失部分加密数据。将最后一节更新为如下:

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] someData = c.update(textData);
byte[] moreData = c.doFinal();

System.out.println("E: " + (someData.length + moreData.length));

c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.DECRYPT_MODE, k, iv);
byte[] someDecrypted = c.update(someData);
byte[] moreDecrypted = c.doFinal(moreData);

System.out.println("R: " + (someDecrypted.length + moreDecrypted.length));

回答by laz

You can forgo the calls to updateand just pass the byte[]data directly to doFinalperforming the operation of encrypting or decrypting in one step.

您可以放弃调用update,直接传递byte[]数据doFinal,一步完成加解密操作。