Проблема с расшифровкой шифра: javax.crypto.IllegalBlockSizeException: последний блок неполный при расшифровке

Мне нужно зашифровать и расшифровать файл в Android, а зашифрованный файл (изображение, видео) можно расшифровать и с другого устройства.

Я шифрую и расшифровываю на одном устройстве, все работает нормально, но когда я переключаю пользователя устройства, зашифрованный файл для расшифровки показывает мне ошибку в doFinal()

javax.crypto.IllegalBlockSizeException: последний блок незавершен при расшифровке

это любой способ зашифровать файл с одного устройства и получить доступ ко всем другим устройствам, таким как шифрование паролей в android. И, используя этот ключ пароля на другом устройстве, мы получаем доступ к информации о файле.

// код

private boolean encrypt() {
        try {
            String path = Environment.getExternalStorageDirectory() + File.separator + "Download/tools.png";
            String pathe = Environment.getExternalStorageDirectory() + File.separator + "Download/tools.png";
            byte[] fileData = FileUtils.readFile(path);
            byte[] encodedBytes = EncryptDecryptUtils.encode(EncryptDecryptUtils.getInstance(this).getSecretKey(), fileData);
            FileUtils.saveFile(encodedBytes, pathe);
            return true;
        } catch (Exception e) {
           Toast.makeText(this, "File Encryption failed.\nException: " + e.getMessage(), Toast.LENGTH_SHORT).show();

        }
        return false;
    }

    /**
     * Decrypt and return the decoded bytes
     *
     * @return
     */
    private byte[] decrypt() {

        try {
            String pathe = Environment.getExternalStorageDirectory() + File.separator + "Download/tools.png";
            byte[] fileData = FileUtils.readFile(pathe);
            byte[] decryptedBytes = EncryptDecryptUtils.decode(EncryptDecryptUtils.getInstance(this).getSecretKey(), fileData);
            return decryptedBytes;
        } catch (Exception e) {
         Toast.makeText(this, "File Decryption failed.\nException: " + e.getMessage(), Toast.LENGTH_SHORT).show();

          }
        return null;
    }

Ниже приведен код класса EncryptDecryptUtils.

public static byte[] encode(SecretKey yourKey, byte[] fileData)
            throws Exception {
        byte[] data = yourKey.getEncoded();
        SecretKeySpec skeySpec = new SecretKeySpec(data, 0, data.length, EncoDecode.KEY_SPEC_ALGORITHM);
        Cipher cipher = Cipher.getInstance(EncoDecode.CIPHER_ALGORITHM, EncoDecode.PROVIDER);
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
        return cipher.doFinal(fileData);
    }
public static byte[] decode(SecretKey yourKey, byte[] fileData)
        throws Exception {
    byte[] decrypted;
    Cipher cipher = Cipher.getInstance(EncoDecode.CIPHER_ALGORITHM, EncoDecode.PROVIDER);
    cipher.init(Cipher.DECRYPT_MODE, yourKey, new IvParameterSpec(new byte[cipher.getBlockSize()]));
    Log.d("value ", "decode() returned: " + cipher.toString());
    decrypted = cipher.doFinal(fileData);
    Log.d("", "decode() returned: " + decrypted.length);
    return decrypted;
}



public SecretKey getSecretKey() {
        String encodedKey = "8qkWUsFfdY8yy5lIad4rjw==";
        byte[] decodedKey = Base64.decode(encodedKey, Base64.NO_WRAP);
        SecretKey originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, EncoDecode.KEY_SPEC_ALGORITHM);
        return originalKey;
    }

person Ravi Jat    schedule 24.10.2018    source источник
comment
выложи код пожалуйста   -  person kelalaka    schedule 24.10.2018
comment
у меня есть код, который используется для шифрования и дешифрования   -  person Ravi Jat    schedule 24.10.2018
comment
попробуйте преобразовать Base64.encodeBase64String (зашифровано); byte[] зашифровано = cipher.doFinal(value.getBytes()); завершить декодирование перед расшифровкой.   -  person kelalaka    schedule 24.10.2018
comment
я использую этот код: String encodedKey = Base64.encodeToString(secretKey.getEncoded(), Base64.NO_WRAP); prefUtils.saveSecretKey(encodedKey); и получить значение в getSecretKey String encodedKey = prefUtils.getSecretKey(); вместо String encodedKey = 8qkWUsFfdY8yy5lIad4rjw==; но не рабочий   -  person Ravi Jat    schedule 24.10.2018
comment
это может вам помочь   -  person kelalaka    schedule 24.10.2018
comment
Разные устройства могут использовать разные значения по умолчанию. Не полагайтесь ни на какие системные значения по умолчанию, вместо этого прямо говорите, что вы используете для всего. Как правило, это будет означать использование версии функции с большим количеством параметров, поэтому все параметры указаны, а не предполагаются. Например, не используйте String.getBytes(), вместо этого используйте String.getBytes(UTF-8) или что-то еще, чтобы кодировка символов была указана явно.   -  person rossum    schedule 24.10.2018


Ответы (1)


Вы получаете IllegalBlockSizeException при расшифровке, поскольку данные, которые вы предоставляете для расшифровки, не являются кратным размеру блока шифровальных шифров. Шифрование в блочном режиме не приведет к получению данных с недопустимым размером блока, поэтому вы можете с высокой уверенностью сделать вывод, что ваши данные были каким-то образом повреждены с момента, когда они покинули шифрование, до того, как они вошли в расшифровку.

Вы можете легко проверить это, распечатав размер вывода return cipher.doFinal(fileData); в вашем методе encode(..) и размер fileData в вашем decode(..) непосредственно перед вашим decrypted = cipher.doFinal(fileData);. Они должны быть одинаковыми, а также быть кратным размеру блока шифра.

Выяснение того, почему данные не совпадают, - это просто вопрос отладки, пока вы не найдете виновника.

person Ebbe M. Pedersen    schedule 24.10.2018