When I delete files that are stored in external storage e.g. photos
Is there a way to delete the file using a 'hard' delete such that it cannot be recovered easily?
i.e. if other apps have access to external storage, I don't want them recovering photos that were deleted already
Ordinary apps without root access already have no means to recover deleted files. Once unlink is invoked, the file is gone, period.
Apps with root access can potentially recover an unlinked file by directly reading raw virtual device files (/dev/storage/*). Both removing a file and moving it to different directory merely removes directory entry without touching file contents (they are simply marked as "unused" if file is no longer referenced anywhere). Thus it is possible to gather residual sectors, that previously belonged to file and haven't been overwritten since removal. Preventing this can be varying degree of hard depending on specific filesystem. The external filesystem on most external storage is vFAT. In vFAT it is possible to prevent residual sectors by opening the file before removing and overwriting it's full length with zeroes. Other filesystems (most notably, Samsung's F2FS) might take measures, that make securely removing files a lot harder due to wear-leveling built directly into the filesystem itself.
Do not bother with defending against circuit-level wear-leveling. It happens on such low level, that recovering the data is infeasible without butchering the phone and using a tunneling microscope. Only flash controller firmware can see that data, and most controllers do not allow access to the flash firmware from OS programs.
Of course, you still have to ensure, that the file haven't been cached in some secondary storage facility (for example, the thumbnail of image may have gotten cached in thumbnail cache, or in system MediaProvider). And of course, some other program might have copied the file to somewhere prior to the removal. Therefore, the safest way to assure "secure removal" is encrypting the files: even if someone steals them prior to removal or restores their contents after removal, without a decryption key those contents are useless. Byte-by-byte overwrite comes second.
Some people might suggest a tough brute-force approach: after unlinking a file, create a throwaway temporary file and fill it with amount of random data equal to free space remaining on partition. That will efficiently defeat all forms of wear-leveling and prevent file recovery in most cases. Unfortunately, this method is very slow, extremely taxing on flash memory and does not defend against apps, that previously copied the file.
"unlinking" is a term, traditionally used to describe removal a file in Linux (google for "inodes"). Removing a file with File#delete does unlink it
I think if you are worried about data protection from recovery, you should complete next steps:
open a file for writing
write a random sequence of data instead of real data in this file
delete that file.
Related
My app needs to download and save a big number of images and mp3s.
These will make sense only for the app, only my app will be able to use them in an meaningful way. The user or other apps won't know what to do with them.
Where should I keep them, in external or internal storage?
I'd like to keep them in internal memory because they are only meaningful to the app, and they will be wiped out when the app is deleted.
However, for old devices the internal memory is very limited, and I think it would be a hassle for the user to keep these files here.
So, I was thinking about external memory, but I don't like the idea of keeping those files there after the app has been deleted.
What would be the best practice for this?
Thank you.
Use the path returned by 'getExternalFilesDir(String type)'
From the documentation:
"Returns the absolute path to the directory on the primary external filesystem (that is somewhere on Environment.getExternalStorageDirectory()) where the application can place persistent files it owns. These files are internal to the applications, and not typically visible to the user as media.
This is like getFilesDir() in that these files will be deleted when the application is uninstalled, however there are some important differences:
External files are not always available: they will disappear if the user mounts the external storage on a computer or removes it. See the APIs on Environment for information in the storage state.There is no security enforced with these files. For example, any application holding WRITE_EXTERNAL_STORAGE can write to these files."
For further details: http://developer.android.com/reference/android/content/Context.html#getExternalFilesDir(java.lang.String)
So yes, you can use external storage and have the files deleted when the app is uninstalled (as long as you are happy with the lack of security).
This is pretty close to an opinion question and will likely get closed.
Short answer: Use external storage. Users will get mad if you're filling up their internal storage with tons of files.
Recommendation: Give the users a toggle option to store it wherever they want!
The idea is that.
My application allows user to listen to music and watch videos from the social network. User can save these files in cache to be able to play them offline. This data is saved to SD-card and can be accessed by file managers e t.c.
I want to limit access to these files to other application. The most obvious solution is data encryption.
Can you please recommend me some libraries or frameworks for quick file encryption/decription? It is very desirable to encrypt files "on the fly" during the are loading.
Would this procedure be too slow and resource intensive?
May be there exist some other ways - protected folder in the SD filesystem or something like that?
Yes there is a more standard way to do this.
By using openFileInput on your Context and setting the MODE_PRIVATE flag, you will be able to create files and even folders within your application. Also, these resources will be completely private to your application.
EDIT :
Most of the time, these files will be stored in /data/data/<app_package_name>/files. That is, on the phone memory most of the time, although this is implementation specific.
Regarding the comment of #Carlos mentionning file spamming, yeah you can flood the NAND with multiple files, but /data will be in most cases mounted on a dedicated partition. So you'll be hitting the virtual size of the partition at some point. Please look at this post, the accepted answer gives more details about this.
In fewer words, this is implementation specific (depends on the manufacturer).
Your only option would be to use Encryption, if you want to keep using the external storage. SpongyCastle can help with that. It is an android version of the BouncyCastle APIs.
Apart from that, you could move your files to the internal storage, which may not be feasible in your case as media files tend to be big, and internal storage on most devices is very limited. Even if you do move them to internal storage, any rooted user can access them (or any app with root privileges).
Protecting the folder isn't an option, as anything on the external storage is available to any app with permission to access the external storage. There is nothing you can do about that.
I making an application with phonegap/cordova where I need to keep a lot of files up to date. Some files (mainly images) will need to be erased in time, and some new ones will get downloaded. The thing is, in Android, to manipulate those files, it seems I need to have them on the sdcard; so I copy the files the app starts with from my assets folder to the sdcard. It just seems like a waste of memory space.
Do you know if is there anyway I can start with the app having those files the app starts with already inside the sdcard? or at least somewhere I can delete them later?
Thank you.
Files that are delivered to the device as part of your APK will be stored in a form that cannot be modified by your application (other than by updating to a new version of the apk).
If you copy the files out of the APK into the private internal storage area or the external storage area, those copies can be modified, but the originals inside the apk will remain.
The most efficient solution may be to not put these files in your apk, but have your app instead download them separately on the first run, using whatever mechanism you wanted to use to change them in the future.
(Some people object to this feeling that such files are less secure against unauthorized use, but as the contents of an .apk are trivial to extract this is not a strong argument. Needing to maintain a server to download from is a slightly more substantial objection.)
You do not need to store the files on the SD Card. Each app has its own internal storage that is not accessible by any other apps. For more information see the official docs: http://developer.android.com/guide/topics/data/data-storage.html
I am trying to decide where to store images that are sent as part of instant messages coming in to an app. These messages are viewable in a conversation history view for sometimes a significant period of time after their original receipt. You can imagine any number of other use cases that would have a similar requirement, so the question here is on the "best practice for storing an indeterminate quantity and size of images"
Assumptions
SQLite storage is clearly a bad option since the image size is not
bounded.
It is neither desirable nor undesirable that these images be publicly available to other apps or discoverable by MediaScanner. We are assumed to be perfectly neutral on this point...
This leaves two parts to this question:
1. External Storage
It seems like external storage is to be preferred when available because it is likely to have more room than anything else:
The documentation says the following:
...use getExternalCacheDir() to
open a File that represents the external storage directory where you
should save cache files. If the user uninstalls your application,
these files will be automatically deleted. However, during the life of
your application, you should manage these cache files and remove those
that aren't needed in order to preserve file space.
Unlike internal storage cache, there is no statement made about the automatic reclamation of space on external storage by Android. Still the word "cache" makes me nervous.
Question 1: Do these files remain until explicitly deleted regardless?
Question 2: Is there any other external storage other than the cache that is automatically deleted upon app uninstall AND is preferable to the external cache for some specific reason?
2. Internal Storage
Clearly not every device has external storage, so there needs to be a provision for internal storage.
Question 3: Is the only practical difference between the internal cache retrieved through getCacheDir() and files created with openFileOutput(FILENAME, Context.MODE_PRIVATE) that Android may delete files in the cache directory when under pressure for storage space?
Do these files remain until explicitly deleted regardless?
I haven't read the code, but the javadoc explicitely says
The platform does not monitor the space available in external storage, and thus will not automatically delete these files. Note that you should be managing the maximum space you will use for these anyway, just like with getCacheDir().
Is there any other external storage other than the cache that is automatically deleted upon app uninstall AND is preferable?
None that I know of.
practical difference between the internal cache retrieved through getCacheDir() and files created with openFileOutput?
It's just a facility method, AFAIK
I have to store a lot of images that have to be downloaded from the web server. The size of the images might be 80Mb. So I want a guidance where to store them, whether in internal or external storage. Both create some problems for me. Internal storage is as every one knows is very limited but the problem with external storage is that images can be accessed by user. I don't wanna my application images to be exposed to user and changed or deleted. So is there any alternative or is there any technique to safely put data into external storage?
Unfortunately no, external storage has FAT file system, which does not support access restriction. And you simply must not store such large chunks of data in internal memory (or otherwise users will not like you, to put it mildly).
So the only way to go, is to use external storage. If you need some protection, then you may either encrypt/decrypt data. Or just obfuscate data, like changing file extensions, or adding 10 bytes at the beginning of each file. Obfuscation is more efficient resource-wise, but much less protected. Though encryption key can still be extracted from your application, so both of this approaches have their flows.
I would advice to store them in the external storage. If you don't want the user to be able to read it, protect it with an encryption. I think it's a bad idea to impose large data to the user. If the user wants to remove it, you shouldn't want to prevent it. Perhaps consider the possibility of re-download the pictures from the web if it has been deleted.
Use encryption for file content:
i found nice and lightweight sample code on http://www.androidsnippets.com/encryptdecrypt-strings
I recommend saving to external. Preventing the user from deleting his data is not recommended. Also user can format the sdcard to delete it. so you cannot stop the user. You can hide it from him. Just prefix a dot to the folder name to make it hidden.
If you are using Android 2.3, OBB is your choice.
http://developer.android.com/reference/android/os/storage/StorageManager.html
OBBs contain a filesystem that maybe be encrypted on disk and mounted on-demand from an application. OBBs are a good way of providing large amounts of binary assets without packaging them into APKs as they may be multiple gigabytes in size. However, due to their size, they're most likely stored in a shared storage pool accessible from all programs. The system does not guarantee the security of the OBB file itself: if any program modifies the OBB, there is no guarantee that a read from that OBB will produce the expected output.
Related
What is OBB(Opaque Binary Blob) in Android develop site?