Data encryption for the resources in android - android

I am using database files and some text files which I have put in the Assets folder. When any user downloads my APK file and extracts it, he will get my resources from the assets folder easily.
How can I encrypt all my resources so that if anyone gets my resources, he can't use it?

Assuming the asset file is already encrypted, Java's CipherInputStream to decrypt content of the asset file would help your need
// Cipher that holds algorithm (E.g. AES)
Cipher cipher = getCipherProbablyAES();
// Get input stream to that file. Handle IOException on your own
InputStream assetFile = getAssets().open("myEncrypted.txt");
CipherInputStream cipherIS = CipherInputStream(assetFile, cipher);

Related

Android - Write file to assets folder

I want to download some data and store it into a file. I am aware that I cannot write to the assets dir or any other place because of the sole nature of the APK file.
I am wondering, if I create a file with something like:
FileOutputStream fileout = openFileOutput("text.txt", MODE_PRIVATE);
OutputStreamWriter outputWriter = new OutputStreamWriter(fileout);
outputWriter.write("write this string to file.");
outputWriter.close();
Since I cannot write any files to assets or any raw dir, where it will be written?
What will the location of that file be? Where will it be located in the Android file system ?
Since I cannot write any files to assets or any raw dir, where it will be written?
openFileOutput() writes to internal storage.
What will the location of that file be? Where will it be located in the Android file system ?
That can vary by device and user. It will be to the same directory that is returned via a call to getFilesDir().
You can get the path to your file created with openFileOutput like this: MainActivity.this.getFilesDir().getAbsolutePath()+"/text.txt" and you can read it using an object of FileInputStream FileInputStream fis = new FileInputStream(new File(MainActivity.this.getFilesDir().getAbsolutePath()+"/text.txt"));

Is it possible to access a runtime decrypted file in android?

I want to decrypt a file stored at my app's res folder. This file is distributed with the app, and I'm trying to decrypt it only once during app start.
So far, I've found some answers (this one, for instance) about how to write the decrypted file into sdcard, but won't that file be available to malicious access at the sdcard?
I wish I could write the CipherInputStream into a java.io.InputStream, so I could use it without writing any decrypted data to disk. Is it possible?
I think you want something like this
private InputStream getDecodedInputStream (InputStream eis) {
Cipher cipher = Cipher.getInstance("your cipher definition");
cipher.init(Cipher.DECRYPT_MODE, "your keySpec", new IvParameterSpec("your IV parameter spec"));
InputStream decryptedInputStream = new CipherInputStream(is, cipher);
return decryptedInputStream;
}
where eis is your encrypted input stream

Android NDK: read file from assets inside of shared library

In my app I have to pass a file from assets folder to shared library.
I cannot do it with use of jni right now.
I'm using precompiled shared library in my project, in which I have hardcoded path to my file, but I'm getting error "No such file or directory".
So in my .apk file I have .so file in libs/armeabi-v7a folder and my file in /assets folder.
I have tried to do it like this:
char *cert_file = "/assets/cacert.cert";
av_strdup(cert_file);
And some other paths, but it doesn't work.
Is it possible at all?
You can simply use the AAssetManager class in C++.
Basically you need to:
During the init of you library get a pointer on: AAssetManager* assetManager
Use it to read your file:
// Open your file
AAsset* file = AAssetManager_open(assetManager, filePath, AASSET_MODE_BUFFER);
// Get the file length
size_t fileLength = AAsset_getLength(file);
// Allocate memory to read your file
char* fileContent = new char[fileLength+1];
// Read your file
AAsset_read(file, fileContent, fileLength);
// For safety you can add a 0 terminating character at the end of your file ...
fileContent[fileLength] = '\0';
// Do whatever you want with the content of the file
// Free the memoery you allocated earlier
delete [] fileContent;
You can find the official ndk documentation here.
Edit:
To get the AAssetManager object:
In a native activity, you main function as a paramater android_app* app, you just need to get it here: app->activity->assetManager
If you have a Java activity, you need so send throught JNI an instance of the java object AssetManager and then use the function AAssetManager_fromJava()
Your assets are packaged into your apk, so you can't refer to them directly during runtime like in the sample code you provided. You have 2 options here:
Process the assets as an input stream, using
Context.getAssets().open('cacert.cert')
Copy out your asset to a local file in your files dir, and then reference the filename of the copied file.
Building off of the answer by #Sistr , I used getBuffer along with AASSET_MODE_BUFFER (instead of AAsset_read).
However, I was trying to write the buffer to an ofstream. I got signal crashes using the <<operator:
ofstream myStream(<some file>, ios_base::binary);
auto buffer = AAsset_getBuffer(asset);
myStream << buffer;
I presume this is because the buffer pointer points to the asset without a NULL character at the end (I was reading a text asset; Android source code). Using the write function worked:
ofstream myStream(<some file>, ios_base::binary);
auto buffer = AAsset_getBuffer(asset);
myStream.write((char *)buffer, AAsset_getLength(asset));
This is because the <<operator does not have to call strlen to find out how many characters to write since it is explicitly given by AAsset_getLength.

Reading RAW resources and saving into Internal storage

I am trying to create internal storage folder(s) and copy over my RAW files to those folder. I have following method
EDIT
private byte[] buffer = null;
private String DIR_NAME = "images/sample_images";
public void storeRAWFilesToInternalStorage()
{
buffer = new byte[3000000];
mFilesDir = tempContext.getFilesDir();
mImagesDir = new File(mFilesDir, DIR_NAME);
if (!mImagesDir.exists() && !mImagesDir.isDirectory()) dirCreated = mImagesDir.mkdirs();
InputStream fileStream = tempContext.getResources().openRawResource(R.raw.desert);
fileStream.read(buffer);
fileWithinMyDir = new File(mImagesDir, "my_sample_image.jpg");
FileOutputStream outputStream = new FileOutputStream(fileWithinMyDir);
outputStream.write(buffer);
outputStream.close();
}
it works fine, however I have following questions.
What is the buffer size should I assign since I dont know the bytes size of each file. If I assign more than required then I am wasting memory. If I am assigning less than required then image wont be saved properly.
Also, I see the image saved in my Internal Storage (using ES Fileexplorer to view files), but when I try to open it, it doesnt show up. Weird.
END EDIT
Also what if I have 100 RAW files which I would like to copy to my Internal Folder, say "images". I dont want to type following thousand of times.
InputStream fileStream = tempContext.getResources().openRawResource(R.raw.**asset_name**);
Is there a way to loop through all raw resources, read them and store them to Internal Storage folder? Can I see some code snippet?

Write to file in android from input stream?

Im getting an input stream, which is an mp3 in my raw folder, and then I am trying to write it back to the raw folder (I know this sounds stupid but I want to do it), but I get an error - file not found, myFile.mp3. Any ideas where I am going wrong?
try
{
File f=new File("android.resource//com.apps/raw/myFile.mp3");
InputStream myRawResource = context.getActivity().getResources().openRawResource(mp3ID);
OutputStream out=new FileOutputStream(f);
byte buf[]=new byte[1024];
int len;
while((len=myRawResource.read(buf))>0)
out.write(buf,0,len);
out.close();
myRawResource.close();
}
catch (IOException e){
//error
}
You can't write the raw and assets folder in android.
Edit:
Android documentation
I copied the key phrase (Tip from the documentation):
If you want to save a static file in your application at compile time, save the file in your project res/raw/ directory. You can open it with openRawResource(), passing the R.raw. resource ID. This method returns an InputStream that you can use to read the file (but you cannot write to the original file).
This can't be done because resources, at runtime, are read-only, are stored in the APK, and would need to be compiled for inclusion in R at compile time.

Categories

Resources