在Android上将游戏资产下载到SD卡

时间:2010-04-23 09:58:26

标签: android copy-protection sd-card

我正在开发 Android游戏,必须将资产下载到 SD卡,以确保应用的尺寸小尽可能。我正在考虑使用未压缩的zip 文件来捆绑所有资产。

客户要求尽可能保护这些资产。作为apk的一部分被认为是足够的保护,但如果我这样做 apk大小将是巨大的。如果我只是在SD卡中放入一个zip包,那么任何人都可以解压缩并探索其内容。

有没有一种简单的方式来做到这一点而不会反驳到可怕的DRM?

显然,如果某人真的想要检查Android游戏的资源,他们可以。我只是在寻找一个简单的解决方案,以避免让这很容易。

1 个答案:

答案 0 :(得分:4)

你可以encrypt the ZIP file with AES但是提取资产可能会有一些问题,因为在编写游戏时性能通常非常重要。

但是,正如您所说的那样,使用安全加密并不值得,因为如果有人真正感兴趣,他们可以在应用程序的源代码中找到密钥。因此,您可以自己编写InputStreamOutputStream来对ZIP文件的字节执行一些简单的翻译。在阅读文件时可以快速撤消,但会“破坏”ZIP文件,足以阻止某人浏览他们的SD卡。

使用它时,您可以将信息流放在FileZIPInputStream之间,例如:

File assets = new File(Environment.getExternalStorageDirectory(),"assets");
ZipInputStream zip = new ZipInputStream(new TranslateInputStream(assets));

作为示例翻译,您可以使用已知值对所有字节进行异或运算:

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,因为您不关心压缩。只需将所有资产连接在一个大blob中即可。在创建blob时,将每个资产的起始位置和结束位置写入索引文件。然后,索引文件将包含在.apk文件中,以便从应用程序中的大文件中获取所需的数据。由于大blob不是标准格式,人们将无法轻易地从中提取文件。为了更加确定你总是可以用一些其他数据填充文件的开头 - 也许只是一些纯文本 - 以使blob看起来像其他东西。