Как расшифровать файлы с помощью CipherInputStream или почему не работают следующие методы - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть следующая функция для шифрования файлов. Я напечатал результат обоих файлов, и все, кажется, работает должным образом.

Зашифрованный файл изменяется и имеет ту же длину, что и входной файл.

public void encrypt(String password, String filePath){
    InputStream is = null;
    OutputStream os = null;
    CipherOutputStream cos = null;
    try {
        is = new FileInputStream(new File(filePath));
        os = new FileOutputStream(new File(filePath + ".enc"));
        char[] passwordChars = password.toCharArray();
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(passwordChars, salt, 1024, 256);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKey key = new SecretKeySpec(tmp.getEncoded(), "AES");
        Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
        c.init(Cipher.ENCRYPT_MODE, key, iv);
        cos = new CipherOutputStream(os, c);
        byte[] b = new byte[1024];
        while(is.read(b) != -1)
            cos.write(b);
            b = new byte[1024];
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (os != null)
                os.close();
            if (is != null)
                is.close();
            if (cos != null)
                cos.close();
        } catch (IOException e) {

        }
    }
}

Проблема возникает, когда я пытаюсь расшифровать файл впоследствии. Я использую CipherInputStream со следующей функцией:

public void decrypt(String password, String filePath){   
    InputStream is = null;
    OutputStream os = null;
    CipherInputStream cis = null;
    try {
        is = new FileInputStream(new File(filePath));
        os = new FileOutputStream(new File(filePath + ".dec"));
        char[] passwordChars = password.toCharArray();
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(passwordChars, salt, 1024, 256);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKey key = new SecretKeySpec(tmp.getEncoded(), "AES");
        Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
        c.init(Cipher.DECRYPT_MODE, key, iv);
        cis = new CipherInputStream(is, c);
        byte[] b = new byte[1024];
        while(cis.read(b) != -1){
            os.write(b);
            b = new byte[1024];
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (os != null)
                os.close();
            if (is != null)
                is.close();
            if (cis != null)
                cis.close();
        } catch (IOException e) {

        }
    }
}

В то время как l oop не вводится вообще. Он действует так, как будто файл пуст, пока я проверял, и это явно не так. Кажется, шифрование работает правильно, но не расшифровка.

Я попытался изменить функцию на использование CipherOutputStream, но затем произошло то же самое. Я получаю расшифрованный файл длиной 0.

Почему метод дешифрования не работает?

1 Ответ

1 голос
/ 11 февраля 2020

Есть много вещей, которые нужно исправить

c .init (Cipher.ENCRYPT_MODE, ключ, iv);

Где определяется IV? Если это stati c, то, используя режим cb c, вы почти полностью нарушаете безопасность.

Далее - вы используете режим CB C без какой-либо аутентификации (hma c), попробуйте найти «податливый шифр»

Почему метод дешифрования не работает?

byte[] b = new byte[1024];
    while(is.read(b) != -1)
        cos.write(b);
        b = new byte[1024];
    }

Это совершенно неправильно . Вы пишете полный массив b из 1024 байтов независимо от входных данных для чтения. (есть ли причина для воссоздания массива в l oop?)

попробуйте что-то вроде

b=byte[1024];
for(int bytesRead=in.read(b); bytesRead>-1; bytesRead=in.read(b))
   cos.write(b, 0, bytesRead);
 cos.flush()

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

Примечание: мне не очень нравится реализация CipherStream, я бы посоветовал вам использовать cipher.update и cipher.doFinal

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...