Android read file from CipherInputStream without rewrite the file - android

Is there someone who know how to read decrypted file without rewrite it into the original file?
After downloading the file, the file automatically encrypted. When I want to open the file, the file will be decrypted first but the problem is how to read the file from CipherInputStream so that no need to convert the file back to the original.
void decrypt(File file1, String nama) throws IOException, NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException {
md5 hash = new md5();
String sapi = hash.md5(nama);
FileInputStream fis = new FileInputStream(file1+ "/" + sapi);
FileOutputStream fos = new FileOutputStream(file1 + "/decrypted.json");
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(),
"AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
while ((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
I can open the decrypted file but it will duplicate between encrypted and original if I use the code above.

FileOutputStream fos = new FileOutputStream(file1 + "/decrypted.json");
writes to the File object passed in as the first parameter to the decrypt method
decrypt(File file1 ...
Which is also the file object you are reading in.
So when you do fos.write(d, 0, b);you are writing back to that File object which is the same object that you are reading from.
So either write to a different file or just don't write anything out at all.
The new FileOutputStreammethod can take a file name instead of a File object as described here Relevant excerpt states
FileOutputStream (String name,
boolean append)
Creates a file output stream to write to the file with the specified
name. If the second argument is true, then bytes will be written to
the end of the file rather than the beginning. A new FileDescriptor
object is created to represent this file connection.
First, if there is a security manager, its checkWrite method is called
with name as its argument.
If the file exists but is a directory rather than a regular file, does
not exist but cannot be created, or cannot be opened for any other
reason then a FileNotFoundException is thrown.
so maybe you want FileOutputStream fos = new FileOutputStream("/decrypted.json", true|false)
setting the second parameter to either true or false depending on whether or not you want the file appended to or overwritten?
It's a little difficult to provide an exact solution to your problem as you don't clearly state what your desired result is so I have made some assumptions which may be wrong but either way the above should help you find the solution you need

Related

How can I lock a file in android?

So the scenario of my problem is in my application I am fetching some file from the internet then I put them in internal storage then when user wants to access these file User can access them through my application.
I did all the thing but I want to provide some security in my application So what I want is?
User can see my file only in my application. User unable to access them from the file manager. Don't tell me the solution to put dot
before file name or folder name I did that the problem with this
solution is when I access them by putting dot before file name the
file are again visible .
I also want that when the user open my file ,just like a pdf in pdf reader He/She restricted to save or download them through pdf
reader or another application.
Any Kind of help is appreciated by me.
You can encrypt that file so user won't be able to access them. here is the encryption method which works for me.
public void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
// Here you read your file.
FileInputStream fis = new FileInputStream("Path Of your file");
// This stream write the encrypted text. This stream will be wrapped by another stream.
FileOutputStream fos = new FileOutputStream("Path Of your file");
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[8];
while((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
fis.close();
}
Here is the method for decryption of particular file.
public void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream("Path Of your file");
FileOutputStream fos = new FileOutputStream("Path Of your file");
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
while((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();}
you can encrypt your files with an encryption algorithm and save them with your custom file extension then you can make an intent filter for opening them from File Manager and for more security i prefer the JNI For whole Encryption system .

Best way to store pdf files in android

IN our application we are getting byte array from server if login gets success. We are converting those byte array into PDF format and storing those files into DB which using internal memory.If files are in KB , application works properly but of files size get increase in MB then application gives out of memory error.Please tell me how to handle this scenario?How to store files into SD card to maintain security also.It should not visible to outside user.
Please do help.
Thanks,
AA.
You should take a look at:
CipherInputStream and CipherOutputStream. They are used to encrypt and decrypt byte streams.
EDIT: So here you go!
I have a file named cleartext. The file contains:
Hi, I'm a clear text.
How are you?
That's awesome!
Now, you have an encrypt() function:
static void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
// Here you read the cleartext.
FileInputStream fis = new FileInputStream("data/cleartext");
// This stream write the encrypted text. This stream will be wrapped by another stream.
FileOutputStream fos = new FileOutputStream("data/encrypted");
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[8];
while((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
fis.close();
}
After you execute this function, there should be a file names encrypted. The file contains the encrypted characters.
For decryption you have the decrypt function:
static void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream("data/encrypted");
FileOutputStream fos = new FileOutputStream("data/decrypted");
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
while((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
After the execution of decrypt, there should be a file named decrypted. This file contains the free text.
Edit: You write you're a "noob" but depending on the use-case of encryption you could do a lot of harm if you're not doing it the right way. Know your tools!
Usage of CipherOutputStream Oracle documentation:
SecretKeySpec skeySpec = new SecretKeySpec(y.getBytes(), "AES");
FileInputStream fis;
FileOutputStream fos;
CipherOutputStream cos;
// File you are reading from
fis = new FileInputStream("/tmp/a.txt");
// File output
fos = new FileOutputStream("/tmp/b.txt");
// Here the file is encrypted. The cipher1 has to be created.
// Key Length should be 128, 192 or 256 bit => i.e. 16 byte
SecretKeySpec skeySpec = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
Cipher cipher1 = Cipher.getInstance("AES");
cipher1.init(Cipher.ENCRYPT_MODE, skeySpec);
cos = new CipherOutputStream(fos, cipher1);
// Here you read from the file in fis and write to cos.
byte[] b = new byte[8];
int i = fis.read(b);
while (i != -1) {
cos.write(b, 0, i);
i = fis.read(b);
}
cos.flush();
Thus, the encryption should work. When you reverse the process, you should be able to read the decrypted bytes.
Storing on the SD card will make the file accessible to savvy users. Storing in the db will give you errors like you mentioned. Probably the best idea would be to go to internal storage. This isn't perfect (rooted users can browse to the files), but it's probably the best option.
http://developer.android.com/guide/topics/data/data-storage.html#filesInternal

How to lock Android folder programmatically?

I am making an Android application, and I want to prevent users from opening some folder. In that folder user can store image or video files. It would be great if I could protect that folder with password.
Which is the best way to do that?
Here is Both function for encrypt and decrypt file in Sdcard folder.
we can not lock folder but we can encrypt file using AES in Android, it may help you.
static void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
// Here you read the cleartext.
FileInputStream fis = new FileInputStream("data/cleartext");
// This stream write the encrypted text. This stream will be wrapped by another stream.
FileOutputStream fos = new FileOutputStream("data/encrypted");
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[8];
while((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
fis.close();
}
static void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream("data/encrypted");
FileOutputStream fos = new FileOutputStream("data/decrypted");
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
while((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
You should save this information on the internal storage. Normally other apps can't access these files. From the quideliness:
You can save files directly on the device's internal storage. By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user). When the user uninstalls your application, these files are removed.
See the link: http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
Insted of LOCK i will saggest you make folder with . like foldername -> .test
user cant see that folder here is code
File direct = new File(Environment.getExternalStorageDirectory() + "/.test");
if(!direct.exists())
{
if(direct.mkdir())
{
//directory is created;
}
}
above code is create folder with name ".test" (in SD CARD) then save your data(file, video.. whatever) in this folder user cant access it.
if you create folder in internal storage then if user clear data of your app then that folder may EMPTY!

Android- Is there a way to decrypt the apk file in MODE_PRIVATE

I want to decrypt the encrypted apk file in private mode, I know it is possible to decrypt it to a particular location.
Im using the following code to decrypt it to a sdcard.
FileInputStream fis = new FileInputStream("/sdcard/encrypted.apk");
FileOutputStream fos = new FileOutputStream("/sdcard/decrypted.apk");
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
while((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
But is it possible to decrypt apk file in a private mode...?
It looks like you are mixing things up. MODE_PRIVATE or in detail Context.MODE_PRIVATE is used if you want to create a file in the app's data directory.
Using MODE_PRIVATE doesn't make use of encryption at all, it simply sets the file access permissions so that only the app itself can access the file.
On a lot of devices the /sdcard section is a separate partition or sd-card formatted with fat32 - which does not support permissions on file-level at all. Therefore MODE_PRIVATE will not work on the path.
If you need a FileOutputStream in MODE_PRIVATE you can simply call:
FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
The context is the Context of your App. It will work at least in the app's private data directory.

how can i play video from byte in android

I have video in my project. and for security i encrypt the video files which is working quite well.
but problem is that the
**videoView.setVideoPath("/mnt/sdcard/intro_video.3gp");**
In this method I have to pass the file.(which is decrypted)
so I am creating decrypted file on sdcard for path of file is that possible to pass bytes (which are decrypted) directly in video view. I am using Cipher for encrypt.
Here is my code for
private void decryption()throws Exception {
// TODO Auto-generated method stub
String filePath2 = path + "en/encVideo";
String filePath3 = path + "de/decVideo";
File decfile = new File(filePath3);
if(!decfile.exists())
decfile.createNewFile();
File outfile = new File(filePath2);
int read;
FileInputStream encfis = new FileInputStream(outfile);
Cipher decipher = Cipher.getInstance("AES");
decipher.init(Cipher.DECRYPT_MODE, skey);
FileOutputStream decfos = new FileOutputStream(decfile);
CipherOutputStream cos = new CipherOutputStream(decfos,decipher);
while((read=encfis.read()) != -1)
{
cos.write(read);
cos.flush();
}
cos.close();
}
If streaming the video to a VideoView without an intermediary file to store the decrypted version is what you are looking for, then the answer is Yes you can do it. You need two main components: a streaming server such as a local http instance and CipherInputStream.
I doubt you can do it. Since you are using VideoView, it would require specific headers and tail ends that suggest which format and how it is encoded etc. If you can figure out that I still doubt it can take raw file. Your best bet would be to create random file names while saving and passing that to the player.

Categories

Resources