java - AES/CBC/PKCS5填充问题

标签 java cryptography aes jce

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

我有以下代码:

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

}

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

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)

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

最佳答案

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

关于java - AES/CBC/PKCS5填充问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11065063/

相关文章:

java - Java中比较字符串的三种不同方式

javascript - 尝试在nodejs中自己验证JWT签名以了解JWT的内部工作原理,但解密的签名给出错误的值

iphone - 在 iOS 上使用 RSA-SHA1 的 OAuth 签名

java - Rijndael AES、addRoundKey、异或十六进制字符串并将它们存储为字节

java - 将 AlertDialog 转换为布局

java - 这里需要显式解码吗?

java - 在 android/java 应用程序中测试加密功能性能(及时测量)的最佳方法?

java - AES加密算法输出字符串长度(String)错误?

c# - 得到错误 : "Specified block size is not valid for this algorithm" while initialize AesCryptoProvider

java - java线程安全-集合/列表