Вы можете зашифровать ZIP-файл с помощью AES , но при извлечении ресурсов могут возникнуть накладные расходы, что может быть проблемой, поскольку производительность при написании игры обычно очень важна.
ОднакоКак вы уже сказали, использование безопасного шифрования на самом деле не имеет смысла, поскольку, если кто-то действительно заинтересован, он может найти ключи в исходном коде вашего приложения.Таким образом, вы можете написать InputStream
и OutputStream
самостоятельно, чтобы выполнить тривиальный перевод байтов ZIP-файла.Это было бы быстро отменить при чтении файла, но «повредило» ZIP-файл достаточно, чтобы помешать кому-то просто просматривать их SD-карту.
При использовании вы помещаете ваш поток между File
и ZIPInputStream
, например:
File assets = new File(Environment.getExternalStorageDirectory(),"assets");
ZipInputStream zip = new ZipInputStream(new TranslateInputStream(assets));
В качестве примера перевода вы можете просто XOR для всех байтов с известным значением:
private static final byte MAGIC_NUMBER = 13;
private void translateBuffer(byte[] buffer) {
for (int i = 0;i < buffer.length;i++) {
buffer[i] ^= MAGIC_NUMBER;
}
}
private class TranslateOutputStream extends FileOutputStream {
public TranslateOutputStream(File file) throws FileNotFoundException {
super(file);
}
@Override
public void write(int oneByte) throws IOException {
oneByte ^= MAGIC_NUMBER;
super.write(oneByte);
}
//In Android write(byte[]) calls this method so we don't need to override both
@Override
public void write(byte[] buffer, int offset, int count)
throws IOException {
translateBuffer(buffer);
super.write(buffer, offset, count);
}
}
private class TranslateInputStream extends FileInputStream {
public TranslateInputStream(File file) throws FileNotFoundException {
super(file);
}
@Override
public int read() throws IOException {
return super.read() ^ MAGIC_NUMBER;
}
//In Android read(byte[]) calls this method so we don't need to override both
@Override
public int read(byte[] buffer, int offset, int count)
throws IOException {
int bytesRead = super.read(buffer, offset, count);
translateBuffer(buffer);
return bytesRead;
}
}
В качестве альтернативы, вы не можете использовать ZIP кактебя не волнует сжатие.Просто объедините все активы в один большой объект.При создании большого двоичного объекта запишите начальное и конечное местоположение каждого актива в индексный файл.Затем индексный файл будет включен в ваш файл .apk, что позволит вам получить необходимые данные из большого файла в вашем приложении.Поскольку большой двоичный объект не был бы в стандартном формате, люди не смогли бы легко извлечь из него файлы.Чтобы быть уверенным, вы всегда можете дополнить начало файла некоторыми другими данными - возможно, просто каким-нибудь простым текстом - чтобы блоб выглядел как-то еще.