簡體   English   中英

使用aes / ecb / pkcs5padding解密字節數組時出現IllegalBlockSizeException

[英]IllegalBlockSizeException when using aes/ecb/pkcs5padding to decrypt a byte array

我知道aes加密需要在16塊中,但我的印象是使用Cipher.getInstance("AES/ECB/PKCS5PADDING"); 填充字節數組來實現這一點。 我的代碼如下:

CipherUtils.java

private static byte[] key = {
        0x74, 0x68, 0x69, 0x73, 0x49, 0x73, 0x41, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79
};//"thisIsASecretKey";

public static byte[] EncryptByteArray(byte[] array)
{
    try
    {
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
        SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

        return (cipher.doFinal(array));
    }
    catch (Exception e)
    {
      e.printStackTrace();

    }
    return null;
}

public static byte[] DecryptByteArray(byte[] array)
{
    try
    {
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
        SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);

        return cipher.doFinal(array);
    }
    catch (Exception e)
    {
      e.printStackTrace();

    }
    return null;
}

主要計划

        fis = new FileInputStream(path);

        toDecrypt = new byte[fis.available()+1];

        int content;
        int i = 0;
        while ((content = fis.read()) != -1) {

            // convert to byte and display it
            toDecrypt[i] = (byte)content;
            i += 1;
        }

        byte[] decryptedStr = CipherUtils.DecryptByteArray(toDecrypt);

        FileOutputStream decryptedStream = new FileOutputStream(path);
        decryptedStream.write (decryptedStr);
        decryptedStream.close();

path中的文件使用cipherutils.java中的函數加密,並使用FileOutputStream.write寫入文件

更新 - 我正在使用Gradle為Android構建。

這就是問題:

toDecrypt = new byte[fis.available()+1];

首先,您使用的是available()方法,這絕不是一個好主意。 其次,即使假設返回該文件的長度,您要添加1到它-為什么? 你肯定只需要文件中的字節。

最簡單的方法是使用Files.readAllBytes

byte[] toDecrypt = Files.readAllBytes(Paths.get(path));
// TODO: Change the method name to follow Java conventions
byte[] decrypted = CipherUtils.DecryptByteArray(toDecrypt);
Files.write(Paths.get(path), decrypted);

現在你不需要擔心關閉文件流,...(如果你設法解密,你可能無法寫,因為你仍然打開文件閱讀你的文件當前代碼。)

我還強烈建議您重新訪問異常“處理”:

  • 捕捉Exception幾乎總是一個壞主意
  • 調用e.printStackTrace()然后繼續,好像什么也沒發生幾乎總是一個壞主意

使用@ JonSkeet的答案管理好工作(謝謝!):

        File file = new File(path);
        fis = new FileInputStream(file);

        toDecrypt = new byte[(int)file.length()];
        fis.read(toDecrypt);

        byte[] decrypted = CipherUtils.DecryptByteArray(toDecrypt);
        FileOutputStream decryptedStream = new FileOutputStream(bookPath);
        decryptedStream.write (decrypted);
        decryptedStream.close();

正如他所指出的那樣,我不應該使用available()方法。 寫入文件的方法比迭代每個字節要好得多! 根據評論,我還使用隨機IV將加密更改為CBC模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM