3

簡単なテキストを暗号化および復号化しようとしています。しかし、何らかの理由で奇妙なエラーが発生しています: 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 バイトの長さですが、それでも「適切にパディングされていません」?

4

2 に答える 2

4

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));
于 2012-06-16T16:30:47.983 に答える
4

への呼び出しをやめて、データを直接update渡すだけで、暗号化または復号化の操作を 1 ステップで実行できます。byte[]doFinal

于 2012-06-16T18:40:49.243 に答える