Шифрование Java не расшифровывается на Android - PullRequest
1 голос
/ 06 ноября 2019

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

Итак, я узнал, что Bouncy Castle совершенно отличается от стандартной библиотеки шифрования JVM / JDK, поэтому я не уверен на 100%если это проблема. Однако это имело бы смысл. Проблема в том, что если это так, я не знаю, как использовать библиотеку JVM / JDK для шифрования на моем Android. Я не хочу слишком использовать библиотеку Bouncy Castle на моем компьютере.

public static void encrypt(File source, File dest, String password){
    try{
        FileInputStream inFile = new FileInputStream(source.getPath());
        FileOutputStream outFile = new FileOutputStream(dest.getPath());

        byte[] salt = new byte[8], iv = new byte[16];

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
        SecretKey secretKey = factory.generateSecret(keySpec);
        SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(iv));

        byte[] input = new byte[64];
        int bytesRead;

        while((bytesRead = inFile.read(input)) != -1){
            byte[] output = cipher.update(input, 0, bytesRead);
            if(output != null){
                outFile.write(output);
            }
        }

        byte[] output = cipher.doFinal();
        if(output != null){
            outFile.write(output);
        }

        inFile.close();
        outFile.flush();
        outFile.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}

public static void decrypt(File source, File dest, String password){
    try{
        byte[] salt = new byte[8], iv = new byte[16];

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
        SecretKey tmp = factory.generateSecret(keySpec);
        SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
        FileInputStream fis = new FileInputStream(source.getPath());
        FileOutputStream fos = new FileOutputStream(dest.getPath());
        byte[] in = new byte[64];
        int read;
        while((read = fis.read(in)) != -1){
            byte[] output = cipher.update(in, 0, read);
            if(output != null){
                fos.write(output);
            }
        }

        byte[] output = cipher.doFinal();
        if(output != null){
            fos.write(output);
        }
        fis.close();
        fos.flush();
        fos.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}

В результате вы также сможете зашифровать любой файл на моем компьютере, используя стандартную библиотеку шифрования JVM / JDK и имея возможностьрасшифровать тот же файл с моим Android.

Однако, если есть другая библиотека, кроме Bouncy Castle, которая будет работать с Android, я открыт для идей.

1 Ответ

1 голос
/ 06 ноября 2019

Я столкнулся с подобной проблемой. Сначала проверьте правильность настройки шифрования и дешифрования.

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

Затем сначала декодировать кодировку Base64 на мобильный телефон, а затем расшифровать файл.

Проблема возникает из-за того, что некоторые символы не подходят для сохранения или переноса между носителями. На них также влияет базовая ОС. Даже если бит будет изменен, весь ваш расшифрованный текст будет изменен, это может иметь место здесь

КОД ANDROID

public static void decrypt(File source, File dest, String password){
    try{
        Base64InputStream fis = new Base64InputStream(new DataInputStream(new FileInputStream(source.getPath())), Base64.DEFAULT);
        FileOutputStream fos = new FileOutputStream(dest.getPath());


        byte[] salt = new byte[8], iv = new byte[16];

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
        SecretKey tmp = factory.generateSecret(keySpec);
        SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));

        byte[] in = new byte[64];
        int read;
        while((read = fis.read(in)) != -1){
            byte[] output = cipher.update(in, 0, read);
            if(output != null){
                fos.write(output);
            }
        }

        byte[] output = cipher.doFinal();
        if(output != null){
            fos.write(output);
        }
        fis.close();
        fos.flush();
        fos.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}

Обычная JVM

public static void encrypt(File source, File dest, String password){
    try{
        FileInputStream inFile = new FileInputStream(source.getPath());
        OutputStream outFile = Base64.getEncoder().wrap(new FileOutputStream(dest.getPath()));

        byte[] salt = new byte[8], iv = new byte[16];

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
        SecretKey secretKey = factory.generateSecret(keySpec);
        SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(iv));

        byte[] input = new byte[64];
        int bytesRead;

        while((bytesRead = inFile.read(input)) != -1){
            byte[] output = cipher.update(input, 0, bytesRead);
            if(output != null){
                outFile.write(output);
            }
        }

        byte[] output = cipher.doFinal();
        if(output != null){
            outFile.write(output);
        }

        inFile.close();
        outFile.flush();
        outFile.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}

public static void decrypt(File source, File dest, String password){
    try{
        InputStream fis = Base64.getDecoder().wrap(new FileInputStream(source.getPath()));
        //FileInputStream fis = new FileInputStream(source.getPath());
        FileOutputStream fos = new FileOutputStream(dest.getPath());

        byte[] salt = new byte[8], iv = new byte[16];

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
        SecretKey tmp = factory.generateSecret(keySpec);
        SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));

        byte[] in = new byte[64];
        int read;
        while((read = fis.read(in)) != -1){
            byte[] output = cipher.update(in, 0, read);
            if(output != null){
                fos.write(output);
            }
        }

        byte[] output = cipher.doFinal();
        if(output != null){
            fos.write(output);
        }
        fis.close();
        fos.flush();
        fos.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...