固定在移动的媒体文件 [英] Securing media files in the mobile

查看:154
本文介绍了固定在移动的媒体文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做一个鸟的目录为Android。它将包含许多图片和音频文件。所有这些文件来自于第三方公司的版权。

I am thinking about developing a birds catalog for Android. It will contain many pictures and audio files. All those files come from a third party company with copyrights.

我的应用程序应确保(尽可能),这些媒体文件无法访问,复制或操纵。

My application should assure (as much as possible) that those media files are not accessible, copied or manipulated.

我可以遵循哪些策略?在文件系统中的文件地穴和解密内存中显示或播放之前?让他们到SQL精简版为CLOB的?这是SQL精简版,从其他应用程序访问抑或是隐藏应用程序的其他部分?任何其他的想法?我还没有发现这个在网络上的问题太多的信息。

Which strategies could I follow? Crypt files in file system and decrypt in memory before showing or playing them? Keep them into SQL Lite as CLOBs? Is this SQL Lite accessible from other apps or is it hidden for the rest of apps? Any other ideas? I haven't found too much info about this "issue" on the web.

在此先感谢,

贵弥功。

推荐答案

我建议节约了这些文件到SD卡,而不是你的活动的私人文件,图像/音频文件通常是相当大的(我见过< A HREF =htt​​p://stackoverflow.com/questions/6676204/managing-big-amount-of-data-around-400mb>在这次讨论中你打算处理400 MB,就是这相同的应用程序?)。所以crypting要细,比SQLite的更简单。

I suggest saving these files to the SD card, not to the private file of your Activity, as images/audio files are usually quite big (I have seen in this discussion that you are planning to handle 400 MB, is this the same app?). So crypting should be fine, and more straightforward than SQLite.

类低于允许加密字节的二进制文件:

The class below allows encrypting bytes to binary files:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


public class AESEncrypter {
    public static void encryptToBinaryFile(String password, byte[] bytes, File file) throws EncrypterException {
        try {
            final byte[] rawKey = getRawKey(password.getBytes());
            final FileOutputStream ostream = new FileOutputStream(file, false);

            ostream.write(encrypt(rawKey, bytes));
            ostream.flush();
            ostream.close();

        } catch (IOException e) {
            throw new EncrypterException(e);
        }
    }

public static byte[] decryptFromBinaryFile(String password, File file) throws EncrypterException {
    try {
        final byte[] rawKey = getRawKey(password.getBytes());
        final FileInputStream istream = new FileInputStream(file);
        final byte[] buffer = new byte[(int)file.length()];

        istream.read(buffer);

        return decrypt(rawKey, buffer);

    } catch (IOException e) {
        throw new EncrypterException(e);
    }
}

private static byte[] getRawKey(byte[] seed) throws EncrypterException {
    try {
        final KeyGenerator kgen = KeyGenerator.getInstance("AES");
        final SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");

        sr.setSeed(seed);
        kgen.init(128, sr); // 192 and 256 bits may not be available

        final SecretKey skey = kgen.generateKey();

        return skey.getEncoded();

    } catch (Exception e) {
        throw new EncrypterException(e);
    }
}

private static byte[] encrypt(byte[] raw, byte[] clear) throws EncrypterException {
    try {
        final SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        final Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        return cipher.doFinal(clear);

    } catch (Exception e) {
        throw new EncrypterException(e);
    }
}

private static byte[] decrypt(byte[] raw, byte[] encrypted) throws EncrypterException {
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    try {
        final Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);

        return cipher.doFinal(encrypted);

    } catch (Exception e) {
        throw new EncrypterException(e);
    }
}

}

您还需要这个异常类:

public class EncrypterException extends Exception {
    public EncrypterException (           ) { super(   ); }
    public EncrypterException (String str ) { super(str); }
    public EncrypterException (Throwable e) { super(e);   }
}

然后,您只需要使用接下来生成加密的文件:

Then, you just have to use what follows to generate encrypted files:

encryptToBinaryFile("password", bytesToSaveEncrypted, encryptedFileToSaveTo);

而在你的应用程序,你可以阅读它们通过以下方式:

And in your app, you can read them the following way:

byte [] clearData = decryptFromBinaryFiles("password", encryptedFileToReadFrom);

要使用硬codeD密码可被挖成模糊的code和寻找字符串被黑客攻破。我不知道这是否会成为你的情况有足够的安全级别?

To use an hardcoded password can be hacked by digging into the obfuscated code and looking for strings. I don't know whether this would be a sufficient security level in your case?

如果没有,你可以在活动的私人preferences或使用窍门密码存储,如this.class.getDeclaredMethods()[N] .getName()作为密码。这是更难以找到。

If not, you can store the password in your Activity's private preferences or using tricks such as this.class.getDeclaredMethods()[n].getName() as a password. This is more difficult to find.

关于表演,你要知道,crypting /解密可能需要相当长的时间。这需要一些测试。

About performances, you have to know that crypting / decrypting can take quite a long time. This requires some testing.

有在回答一个很大的错误。此实现播种的SecureRandom ,这是不好的(恶,有些人会说)。

There was a big mistake in my answer. This implementation is seeding SecureRandom, which is bad ('evil', some would say).

有一个简单的方法来绕过这个问题。它详细说明这里在 Android开发博客。我们对此深感抱歉。

There is an easy way to circumvent this issue. It is explained in details here in the Android Developers blog. Sorry about that.

这篇关于固定在移动的媒体文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆