如何处理"最后一个数据块不完整的解密" [英] How to handle "last block incomplete in decryption"

查看:315
本文介绍了如何处理"最后一个数据块不完整的解密"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的类,试图在我的程序包加密,其他地方使用。

I have a simple class to try and wrap encryption for use elsewhere in my program.

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最后一块不完整的解密这么多。这里是堆栈跟踪:

It seems to handle encryption correctly, but not so much when decrypting, which throws a javax.crypto.IllegalBlockSizeException "last block incomplete in decryption" at the highlighted line. Here is the stack trace:


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)

我已经做了撞我的头靠在我的办公桌上,试图弄清楚这一点,一个良好的数额,但如果我取得任何进展可言,它最终是一个不同的异常。我也似乎无法找到太多通过搜索。

I have done a good amount of banging my head against my desk to try and figure this out, but if I get anywhere at all, it ends up being a different exception. I also can't seem to find much by searching.

我在想什么?我想AP preciate任何帮助。

What am I missing? I would appreciate any help.

推荐答案

我不知道这是否与 IllegalBlockSizeException 的问题,但你不应该连接code中的键作为字符串,尤其是没有指定的字符编码​​。如果你想这样做,使用类似BASE-64,其目的是EN code任何二进制的数据,而不是一个字符编码,其中只有某些字节映射到人物。

I don't know if this is the problem with the IllegalBlockSizeException, but you should not encode the key as a String, especially without specifying the character encoding. If you want to do this, use something like Base-64, which is designed to encode any "binary" data, rather than a character encoding, which only maps certain bytes to characters.

的关键是,在一般情况下,要包含不对应于缺省平台编码的字符的字节值。在这种情况下,当您创建字符串字节将被转换为替换字符,U + FFFD(&#xFFFD),以及正确的值会永久丢失。

The key is, in general, going to contain byte values that do not correspond to a character in the default platform encoding. In that case, when you create the String, the byte will be translated to the "replacement character", U+FFFD (�), and the correct value will be irretrievably lost.

尝试使用已损坏字符串重的关键presentation稍后将prevent被恢复明文;有可能的话,可能会导致 IllegalBlockSizeException ,但我怀疑一个无效的填充异常会更容易。

Trying to use that corrupt String representation of the key later will prevent the plaintext from being recovered; it is possible it could cause the IllegalBlockSizeException, but I suspect an invalid padding exception would be more likely.

另一种可能性是,源平台和目标平台的字符编码​​是不同的,而解码的密文结果字节太少。例如,源编码为UTF-8,跨$ P $点输入的一个字符两个字节,而目标编码为ISO-Latin-1的,从而重新presents的字符作为单个字节

Another possibility is that the source platform and the target platform character encodings are different, and that "decoding" the ciphertext results in too few bytes. For example, the source encoding is UTF-8, and interprets two bytes in the input as a single character, while the target encoding is ISO-Latin-1, which represents that character as a single byte.

这篇关于如何处理"最后一个数据块不完整的解密"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆