I am new to Android, and I am trying to encrypt and decrypt a file and want to display in Android device after decrypt.
Here I am downloading the file from the URL and storing in SD card and I don't now how to encrypt the file and then store in SD card and file size may be more then 20MB.
Code:
File downloadFile(String dwnload_file_path) {
File file = null;
try {
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(extStorageDirectory, "SampleFolder");
folder.mkdir();
file = new File(folder, dest_file_path);
try{
file.createNewFile();
}catch (IOException e){
e.printStackTrace();
}
URL url = new URL(dwnload_file_path);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(file);
int totalSize = urlConnection.getContentLength();
byte[] buffer = new byte[MEGABYTE];
int bufferLength = 0;
while((bufferLength = inputStream.read(buffer))>0 ){
fileOutputStream.write(buffer, 0, bufferLength);
}
fileOutputStream.close();
//ToastManager.toast(this, "Download Complete. Open PDF Application installed in the device.");
} catch (final MalformedURLException e) {
//ToastManager.toast(this, "Some error occured. Press try again.");
} catch (final IOException e) {
//ToastManager.toast(this, "Some error occured. Press try again.");
} catch (final Exception e) {
//ToastManager.toast(this, "Failed to download image. Please check your internet connection.");
}
return file;
}
Here I am displaying the file in Android device but after decrypting the file, how can I display it?
Code:
File pdfFile = new File(Environment.getExternalStorageDirectory() + "/SampleFolder/" + "Sample."pref.getString(Constants.PrefConstants.PATH_NAME));
File f = new File(pdfFile.toString());
if(f.exists()) {
Uri path = Uri.fromFile(pdfFile);
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, pref.getString(Constants.PrefConstants.PATH_NAME_APP));
//pdfIntent.setFlags(Intent. FLAG_ACTIVITY_CLEAR_TOP);
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(pdfIntent);
} else {
//uiManager.execute(Constants.Commands.REQGET_INSTRUCTIONS_SCREEN,null);
ToastManager.toast(getApplicationContext(), "No data available...");
}
How can I resolve this issue?
You need to use the SecretKeySpec library .
Example of encrypt method
static void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
// Here you read the cleartext.
FileInputStream fis = new FileInputStream("SampleFolder/yourfilename");
// This stream write the encrypted text. This stream will be wrapped by another stream.
FileOutputStream fos = new FileOutputStream("SampleFolder/yourencryptedfilename");
// Length is 16 byte
// Careful when taking user input!!! https://stackoverflow.com/a/3452620/1188357
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();
}
For decrypt method see the link below.
More details : How to encrypt file from SD card using AES in Android?
Related
I encrypted multiple files in one file in order.
Now I want to decrypt only one of those files. for this purpose I did this:
I got all bytes of encrypted files as array Like this: (first index: byte offset of every file in the encrypted file, second index: length of file bytes in the encrypted file)
int[] file1 = new int[] {0 ,109624}
int[] file2 = new int[] {109624,40480}
int[] file3 = new int[] {150104,153640}
int[] file4 = new int[] {303744,24320}
Now for getting specific file from the encrypted file and decrypt it I should to read the encrypted file. First of all, skip the bytes of previous files.
for skipping them I use this method (for example I want to encrypt file2):
int fromByte = file2[0];
int fileLength = file2[1];
FileInputStream fis = new FileInputStream(sourceFile);
CipherInputStream cis = new CipherInputStream(fis,cipher);
long skipBytes = cis.skip(fromByte);
Then it reads byte to byte of source file in "while" loop and when length of read file bytes equals to fileLength, it breaks loop.
I brought all the codes at the end here.
When I decrypt first file (from byte:0 and file length:109624 and it dosn't need to "skip bytes"), It works well.
But when I decrypt other files (for example for encrypt file2 it needs to skipt 109624 byte from source file), It doesn't work well and created file is not decrypted.
Why it dosn't work for other files?
Here's my codes:
public void decryptFile(File sourceFile, File targetFile, int fromByte, int lengthToRead, SecretKeySpec keySpec) {
try {
FileInputStream fis = new FileInputStream(sourceFile);
FileOutputStream fos = new FileOutputStream(targetFile);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE,keySpec);
CipherInputStream cis = new CipherInputStream(fis,cipher);
int readPart,currentLength = 0, bufferSize = 8;
long skipBytes;
byte[] bytes = new byte[bufferSize];
skipBytes = cis.skip(fromByte);
while ((readPart = cis.read(bytes)) != -1) {
fos.write(bytes,0,readPart);
currentLength += bufferSize;
if (currentLength >= lengthToRead) {
break;
}
}
cis.close();
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
}
Here's My codes for encrypt multiple files in on file:
public void encryptFile(File[] sourceFiles, File targetFile, SecretKeySpec keySpec) {
try {
FileOutputStream fos = new FileOutputStream(targetFile);
FileInputStream fis;
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE,keySpec);
CipherOutputStream cos = new CipherOutputStream(fos,cipher);
int readPart,bufferSize = 8;
byte[] bytes = new byte[bufferSize];
for (File sourceFile : sourceFiles) {
fis = new FileInputStream(sourceFile);
while ((readPart = fis.read(bytes)) != -1) {
cos.write(bytes, 0, readPart);
}
fis.close();
}
cos.flush();
cos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
}
I realized the problem, After many reviews.
There are two problem in this codes:
problem 1: in skip method. we should check the skipBytes and if it is not equal to fromByte, it must repeat. for this purpose add these codes:
while (skipBytes<fromByte) {
fromByte -= skipBytes;
skipBytes = cis.skip(fromByte);
}
problem 2: in encrypt function. if the file length is not multiple of 8, encryption method add some bytes until its length is multiple of 8. for fix this problem we should to add those bytes to the file ourselves before encrypt it. for this purpose add these codes before encrypt every file:
int remaining = (int) (sourceFile.length() % 8);
if (remaining>0) {
BufferedWriter bw = new BufferedWriter(new FileWriter(sourceFile,true));
while (remaining<8) {
bw.write(" ");
remaining++;
}
bw.close();
}
This codes modifies source file. If you want to don't modifying source file, instead of above codes, use this codes after ending encryption while loop:
int remainder = (int)(sourceFile.length() % 8);
if (remainder>0) {
StringBuilder sb = new StringBuilder("");
while (remainder<8) {
sb.append(" ");
remainder++;
}
byte[] additionBytes = sb.toString().getBytes(Charset.forName("UTF-8"));
cos.write(additionBytes, 0, additionBytes.length);
}
I want to encrypt video files stored in SD card
Environment.getExternalStorageDirectory()
I have found that Facebook conceal is good for encrypting large files. I have followed this tutorial Make fast cryptographic operations on Android with Conceal
Here is what i have done up to now.
Encryption method
public void encodeAndSaveFile(File videoFile, String path) {
try {
final byte[] encrypt = new byte[(int) videoFile.length()];
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File directory = cw.getDir(path, Context.MODE_PRIVATE);
File mypath = new File(directory, "en1");
Crypto crypto = new Crypto(new SharedPrefsBackedKeyChain(this), new SystemNativeCryptoLibrary());
if (!crypto.isAvailable()) {
return;
}
OutputStream fileStream = new BufferedOutputStream(
new FileOutputStream(mypath));
OutputStream outputStream = crypto.getCipherOutputStream(
fileStream, new Entity("Passwordd"));
outputStream.write(encrypt);
outputStream.close();
} catch (UnsupportedOperationException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(WebViewActivity.this,"Encrypted",Toast.LENGTH_LONG).show();
}
Decryption method
private void decodeFile(String filename,String path) {
Crypto crypto = new Crypto(new SharedPrefsBackedKeyChain(this),
new SystemNativeCryptoLibrary());
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File directory = cw.getDir(path, Context.MODE_PRIVATE);
File file = new File(directory, filename);
try {
FileInputStream fileStream = new FileInputStream(file);
InputStream inputStream = crypto.getCipherInputStream(fileStream,
new Entity("Password"));
ByteArrayOutputStream out = new ByteArrayOutputStream();
int read;
byte[] buffer = new byte[1024];
while ((read = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(WebViewActivity.this,"Decrypted",Toast.LENGTH_LONG).show();
}
But this code throwing following error at the run time
java.lang.illegalArgumentException: File contains a path separator
Then i have changed "mypath: variable of encodeAndSaveFile to this
File mypath = new File(directory, "en1");
and "file" variable of decodeFile to this
File file = new File(directory, filename);
Then no errors but. Encryption is not happening. Please help to solve this or suggest correct method for video encryption with conceal lib.
We have a requirement to download video from google+/picasa and store it into sdcard.
Can you please any one help me to solve this issue?
google+/picasa
Converting from URI to byte[], then byte[] is stored to file:
InputStream videoStream = getActivity().getContentResolver().openInputStream(videoUri);
byte bytes[] = ByteStreams.toByteArray(videoStream );
videoFile = new File("abcd.mp4");
FileOutputStream out = new FileOutputStream(videoFile);
out.write(bytes);
out.close();
Can you try that one :
public String DownloadFromUrl(String DownloadUrl, String fileName) {
File SDCardRoot = null;
try {
SDCardRoot = Environment.getExternalStorageDirectory();
File files = new File(SDCardRoot+fileName);
int sizeoffile;
if(!files.exists())
{
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File (root.getAbsolutePath());
if(dir.exists()==false) {
dir.mkdirs();
}
URL url = new URL(DownloadUrl);
File file = new File(dir, fileName);
/* Open a connection to that URL. */
URLConnection ucon = url.openConnection();
sizeoffile = ucon.getContentLength();
Log.d("SIZEOFFILE: ", sizeoffile+" BYTE");
/*
* Define InputStreams to read from the URLConnection.
*/
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
/*
* Read bytes to the Buffer until there is nothing more to read(-1).
*/
ByteArrayBuffer baf = new ByteArrayBuffer(5000);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
/* Convert the Bytes read to a String. */
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
}
}
catch (IOException e) {
e.getMessage();
}
return SDCardRoot+fileName; }
Finally i found the solution.
Uri videoUri = data.getData();
File videoFile = null;
final InputStream imageStream;
try {
imageStream = getActivity().getContentResolver().openInputStream(videoUri);
byte bytes[] = ByteStreams.toByteArray(imageStream);//IStoByteArray(imageStream);
videoFile = new File(Environment.getExternalStorageDirectory()+ "/"+System.currentTimeMillis()+".mp4");
videoFile.createNewFile();
FileOutputStream out = new FileOutputStream(videoFile);
out.write(bytes);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (Exception ee){
ee.printStackTrace();
}
I have recently encountered this.
I first discovered that what I'm receiving is a picture rather than a video.
But I didn't understand why Facebook is successfully playing the online video I shared via (Google+'s) Photo.
I then occasionally discovered that the file they're currently giving is a GIF with the original extension in the MediaStore.Images.Media.DISPLAY_NAME section of the contentUri.
Eeek!
I am generating an android application which capable to include over-the-air updation in the android application. So that I am generating a Webservice for getting the versioncode so that I will compare the versioncode of installed application if it is lesser then I will trigger there is an update to install from the server, for this I using below code.
String PATH = Environment.getExternalStorageDirectory() + "/download/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "yourapp.apk");
downloadFile(file_url, outputFile);
installApk();
//downloadfile function
private static void downloadFile(String url, File outputFile) {
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(outputFile));
fos.write(buffer);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("FileNotFoundException",e+"");
return;
} catch (IOException e) {
Log.e("IOException",e+"");
return;
}
}
//install apk file function
private void installApk(){
Intent installer = new Intent();
installer.setAction(android.content.Intent.ACTION_VIEW);
installer.putExtra(Intent.ACTION_PACKAGE_REPLACED, "org.wannatrak.android");
installer.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "yourapp.apk")), "application/vnd.android.package-archive");
installer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(installer);
}
I am generating an android application which capable to include over-the-air updation in the android application. So that I am generating a Webservice for getting the versioncode so that I will compare the versioncode of installed application if it is lesser then I will trigger there is an update to install from the server, for this I using below code.
String PATH = Environment.getExternalStorageDirectory() + "/download/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "yourapp.apk");
downloadFile(file_url, outputFile);
installApk();
//downloadfile function
private static void downloadFile(String url, File outputFile) {
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(outputFile));
fos.write(buffer);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("FileNotFoundException",e+"");
return;
} catch (IOException e) {
Log.e("IOException",e+"");
return;
}
}
//install apk file function
private void installApk(){
Intent installer = new Intent();
installer.setAction(android.content.Intent.ACTION_VIEW);
installer.putExtra(Intent.ACTION_PACKAGE_REPLACED, "org.wannatrak.android");
installer.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "yourapp.apk")), "application/vnd.android.package-archive");
installer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(installer);
}
The above works well upto 4.0 versions.If i try it in the jelly bean I am getting "There is a parse error in a package error" Please help me to solve this issues
Thanks.
You need to give read permission to your apk file. In the install apk file function, add:
File file = new File(Environment.getExternalStorageDirectory() + "/download/" + "yourapp.apk")
file.setReadable(true, false);
installer.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
I Tried following code.
How to read encrypted .epub file (Without saving decrypted file on sd card)
I want to maintain security for .epub file
is it possible to maintain security?
Thanks for Help in prior
static void encrypt() throws IOException, NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException {
// Here you read the cleartext.
String file_en_path = Environment.getExternalStorageDirectory().getAbsolutePath() +"/Decrypted";
File extStore = new File(file_en_path,"text.epub");
FileInputStream fis = new FileInputStream(extStore);
// This stream write the encrypted text. This stream will be wrapped by
// another stream.
File extStore_enc = new File(file_en_path,"text_enc.epub");
FileOutputStream fos = new FileOutputStream(extStore_enc);
Log.d("encrypt--fis------------->>>>>>",""+fis);
Log.d("encrypt--fos------------->>>>>>",""+fos);
// 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 {
String file_de_path = Environment.getExternalStorageDirectory().getAbsolutePath() +"/Decrypted";
File extStore = new File(file_de_path,"text_enc.epub");
//File extStore = Environment.getExternalStorageDirectory();
FileInputStream fis = new FileInputStream(extStore);
File extStore_dec = new File(file_de_path,"text_dec.epub");
FileOutputStream fos = new FileOutputStream(extStore_dec);
//FileOutputStream fos = context.openFileOutput("fontsize_dec.txt",Context.MODE_PRIVATE);
Log.d("decrypt--fis------------->>>>>>",""+fis);
Log.d("decrypt--fos------------->>>>>>",""+fos);
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(),"AES");
IvParameterSpec ivSpec = new IvParameterSpec("MyDifficultPassw".getBytes());
Cipher cipher = Cipher.getInstance("AES");
try {
cipher.init(Cipher.DECRYPT_MODE, sks, ivSpec);
} catch (InvalidAlgorithmParameterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
StringBuilder sb = new StringBuilder();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(cis, "UTF-8"));
/*line = reader.readLine();
sb.append(line);
Log.d("sb.append(line)--------------------------->",""+sb.append(line));*/
while ((line = reader.readLine()) != null) {
sb.append(line);
// Log.d("sb.append(line)--------------------------->",""+sb.append(line));
// Log.d("Line--------------------------->",""+line);
}
Log.d("sb.toSting-------------------->",""+sb.toString());
while ((b = cis.read(d)) != -1) {
//Log.d("cis.read(d)------------------------>>>>>>>",""+cis.read(d));
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}