Как справиться с «неполным расшифровкой последнего блока»

У меня есть простой класс, чтобы попытаться обернуть шифрование для использования где-нибудь в моей программе.

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;

public final class StupidSimpleEncrypter
{
    public static String encrypt(String key, String plaintext)
    {
        byte[] keyBytes = key.getBytes();
        byte[] plaintextBytes = plaintext.getBytes();
        byte[] ciphertextBytes = encrypt(keyBytes, plaintextBytes);
        return new String(ciphertextBytes);
    }

    public static byte[] encrypt(byte[] key, byte[] plaintext)
    {
        try
        {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            SecretKeySpec spec = new SecretKeySpec(getRawKey(key), "AES");
            cipher.init(Cipher.ENCRYPT_MODE, spec);
            return cipher.doFinal(plaintext);
        }
        catch(Exception e)
        {
            // some sort of problem, return null because we can't encrypt it.
            Utility.writeError(e);
            return null;
        }
    }

    public static String decrypt(String key, String ciphertext)
    {
        byte[] keyBytes = key.getBytes();
        byte[] ciphertextBytes = ciphertext.getBytes();
        byte[] plaintextBytes = decrypt(keyBytes, ciphertextBytes);
        return new String(plaintextBytes);
    }

    public static byte[] decrypt(byte[] key, byte[] ciphertext)
    {
        try
        {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            SecretKeySpec spec = new SecretKeySpec(getRawKey(key), "AES");
            cipher.init(Cipher.DECRYPT_MODE, spec);
            return cipher.doFinal(ciphertext);
        }
        catch(Exception e)
        {
            // some sort of problem, return null because we can't encrypt it.
            Utility.writeError(e);
            return null;
        }
    }

    private static byte[] getRawKey(byte[] key)
    {
        try
        {
            KeyGenerator gen = KeyGenerator.getInstance("AES");
            SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
            rand.setSeed(key);
            gen.init(256, rand);
            return gen.generateKey().getEncoded();
        }
        catch(Exception e)
        {
            return null;
        }
    }
}

Похоже, что шифрование обрабатывается правильно, но не столько при дешифровании, которое вызывает исключение javax.crypto.IllegalBlockSizeException «последний блок не завершен при расшифровке» в выделенной строке. Вот трассировка стека:

Location:com.xxxxxx.android.StupidSimpleEncrypter.decrypt ln:49
last block incomplete in decryption
javax.crypto.IllegalBlockSizeException: last block incomplete in decryption
     at org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(JCEBlockCipher.java:711)
     at javax.crypto.Cipher.doFinal(Cipher.java:1090)
     at com.xxxxxx.android.StupidSimpleEncrypter.decrypt(StupidSimpleEncrypter.java:44)
     at com.xxxxxx.android.StupidSimpleEncrypter.decrypt(StupidSimpleEncrypter.java:34)

Я много раз бился головой о стол, пытаясь понять это, но если я вообще куда-нибудь доберусь, это окажется другим исключением. Я также не могу найти много с помощью поиска.

Что мне не хватает? Буду признателен за любую помощь.

12
задан Jake Basile 5 January 2011 в 14:55
поделиться