In my application i have Decrypt file with AES256 and CBC .
i have written below codes, to check if file exists.
But when run application it shows me an error and not can open my file!
I used Log.e to show files's path and it shows me this path. but it says can not open file!
My code :
private SecureRandom r;
private byte[] _iv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
r = new SecureRandom();
_iv = new byte[16];
r.nextBytes(_iv);
String inputFile = getRootDirPath(context) + "/"+bookName;
String outPutFile = getRootDirPath(context) + "/BookFile_716798_decrypt3.html";
File file = new File(inputFile);
if (file.exists()) {
try {
decrypt(inputFile, encryptionPassword, outPutFile, "");
Log.e("DecryptLog", "0");
} catch (IOException e) {
e.printStackTrace();
Log.e("DecryptLog", "1 : " + e.getMessage());
Log.e("DecryptLog", "\nPath : " + inputFile);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
Log.e("DecryptLog", "2 : " + e.getMessage());
} catch (NoSuchPaddingException e) {
e.printStackTrace();
Log.e("DecryptLog", "3 : " + e.getMessage());
} catch (InvalidKeyException e) {
e.printStackTrace();
Log.e("DecryptLog", "4 : " + e.getMessage());
}
} else {
Toast.makeText(context, "Not", Toast.LENGTH_SHORT).show();
}
}
public String getRootDirPath(Context context) {
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
File file = ContextCompat.getExternalFilesDirs(context.getApplicationContext(),
null)[0];
return file.getAbsolutePath();
} else {
return context.getApplicationContext().getFilesDir().getAbsolutePath();
}
}
private void decrypt(String path, String password, String _initVector, String outPath)
throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream(path);
FileOutputStream fos = new FileOutputStream(outPath);
byte[] key = (password).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
SecretKeySpec sks = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
try {
cipher.init(Cipher.DECRYPT_MODE, sks, new IvParameterSpec(_iv));
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
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 run application show me this error :
2020-08-01 08:03:59.324 28560-28560/com.app.appE/DecryptLog: 1 : : open failed: ENOENT (No such file or directory)
2020-08-01 08:03:59.324 28560-28560/com.app.app E/DecryptLog: Path : /storage/emulated/0/Android/data/com.app.app/files/BookFile_716798.html
Related
I am trying to decrypt a file downloaded as ByteArrayOutputStream from Azure Storage.
I have a stream of type ByteArrayOutputStream.
How can I decrypt it and return decrypted ByteArrayOutputStream.?
I have tried using CipherOutputStream, but I'm not sure how to use it.
Below is the code (snippet) I am using to encrypt the file before uploading
cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(INITIALIZATIO_VECTOR.getBytes("UTF-8")));
blob.upload(new CipherInputStream(file.getInputStream(), cipher), file.getSize());
Below is my code:
public ByteArrayOutputStream download(String fileName, Long id) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encrypkey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(INITIALIZATIO_VECTOR.getBytes("UTF-8")));
CipherOutputStream output = null;
container = getBlobClient().getContainerReference("container" + id.toString());
CloudBlockBlob blob = container.getBlockBlobReference(fileName);
if (blob.exists()) {
blob.download(os);
//output = new CipherOutputStream(outputStream, cipher);
} else {
logger.info("File does not exists on azure container");
}
} catch (StorageException e) {
logger.error("StorageException : {}" + e.getLocalizedMessage(), e);
} catch (Exception e) {
logger.error("Exception : {}" + e.getLocalizedMessage(), e);
}
return os;
}
First create the CipherOutputStream, then download the blob into that output:
output = new CipherOutputStream(os, cipher);
blob.download(output);
In my application I want to download an HTML file from server, then decrypt this file and show into webView!
The backend developer uses this library for encrypt file from server: https://github.com/soarecostin/file-vault
I wrote the code below, but when decrypting a file, it shows an error in Logcat and doesn't decrypt this file!
My code:
encryptionPassword = "7BOF%aZQMpfJ#2wUS*S6!#K+ZB$Sz+J0";
String inputFile = FileUtils.getDirPath(this) + "/BookFile_716798.html";
String outPutFile = FileUtils.getDirPath(this) + "/BookFile_716798_decrypt.html";
try {
decrypt(inputFile, encryptionPassword, outPutFile);
Log.e("DecryptLog", "0");
} catch (IOException e) {
e.printStackTrace();
Log.e("DecryptLog", "1");
Log.e("DecryptLog", "" + e.getMessage());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
Log.e("DecryptLog", "2");
} catch (NoSuchPaddingException e) {
e.printStackTrace();
Log.e("DecryptLog", "3");
} catch (InvalidKeyException e) {
e.printStackTrace();
Log.e("DecryptLog", "4");
}
private void decrypt(String path, String password, String outPath)
throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream(path);
FileOutputStream fos = new FileOutputStream(outPath);
byte[] key = (password).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
SecretKeySpec sks = new SecretKeySpec(key, "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();
}
This message is shown in logCat:
2020-07-31 21:52:39.881 1367-1367/com.app.app E/DecryptLog: 1
2020-07-31 21:52:39.881 1367-1367/com.app.appE/DecryptLog: javax.crypto.BadPaddingException: pad block corrupted
How can I fix it?
My app prompts the user for the password that was used to encrypt a control file. If the wrong password is entered, the app responds by creating a new control file. Therefore I need to catch a BadPaddingException so I can trigger the appropriate response.
Here's the code snippet that should generate the exception
private void existingHashFile(String file) {
psUI = new passwordUI(new javax.swing.JFrame(), true, "existing");
psUI.setVisible(true);
this.key = passwordUI.key;
try {
hash.decryptHashFile(file, this.key); //this is line 240
} catch (BadPaddingException ex) {
Logger.getLogger(homePage.class.getName()).log(Level.SEVERE, null, ex);
//then the file was not decrypted
System.out.println("BPE 2!");
} catch (Exception ex) {
Logger.getLogger(homePage.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("BPE 3!");
}
For completeness, here's the decryptHashFile method that is called above
public void decryptHashFile(String filename, String key) throws BadPaddingException, UnsupportedEncodingException, Exception {
FileInputStream fis = null;
FileOutputStream fos = null;
CipherInputStream cis = null;
String outFile = filename.replace(".enc", "");
byte[] byteKey = key.getBytes("UTF-8");
Cipher cipher = getCipher(byteKey, "decrypt");
try {
fis = new FileInputStream(filename);
fos = new FileOutputStream(outFile);
cis = new CipherInputStream(fis, cipher);
byte[] buffer = new byte[1024];
int read = cis.read(buffer);
while (read != -1) {
fos.write(buffer, 0, read);
read = cis.read(buffer); //this is line 197
}
} catch (IOException ex) {
Logger.getLogger(hashListClass.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (fos != null) {
fos.close();
}
if (cis != null) {
cis.close();
}
if (fis != null) {
fis.close();
}
}
}
When I deliberately enter the wrong password, I see this stack trace, but my code (I've used a println in the example) isn't executed:
Dec 02, 2017 2:31:34 PM appwatch.hashListClass decryptHashFile
SEVERE: null
java.io.IOException: javax.crypto.BadPaddingException: Given final block not properly padded
at javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:121)
at javax.crypto.CipherInputStream.read(CipherInputStream.java:239)
at javax.crypto.CipherInputStream.read(CipherInputStream.java:215)
at appwatch.hashListClass.decryptHashFile(hashListClass.java:197)
at appwatch.homePage.existingHashFile(homePage.java:240)
CipherInputStream.read (your line 197) throws IOException, not BadPaddingException, therefore the exception is caught by the subsequent catch (IOException ex).
After that you are not explicitly throwing other exceptions, so there is nothing else to catch after decryptHashFile.
How can we store the KEY in a key file for AES encryption using java so that the key file can be used for decryption purpose.
private static void storeKey(SecretKey key){
byte[] keyb = key.getEncoded();
FileOutputStream keyfos;
try {
File file = new File(generateKeyFilesPath);
if (!file.exists()) {
file.createNewFile();
}
keyfos = new FileOutputStream(file);
keyfos.write(keyb);
keyfos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static SecretKeySpec getKey(String generateKeyFilesPath){
SecretKeySpec key = null;
try {
File keyFile = new File(path);
FileInputStream stream = new FileInputStream(keyFile);
byte[] bytesArray = new byte[(int) keyFile.length()];
stream.read(bytesArray);
stream.close();
key = new SecretKeySpec(bytesArray, "AES");
} catch (Exception e) {
e.printStackTrace();
}
return key;
}
Unable to decrypt the cipher using the stored key(file),
I have the following code and it's OK when creating an encrypted zip file with the given file, however, I could not open the generated zip file with unzip command and it complains invalid zip.
"The Unarchiver" could not unzip as well.
public void encrypt(String desKey, String zipFileName, String fileName) {
InputStream inputStream = null;
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(zipFileName);
SecretKey keySpec = new SecretKeySpec(desKey.getBytes(), "DESede");
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
InputStream cipherInputStream = new CipherInputStream(fileInputStream, cipher);
ZipInputStream zipInputStream = new ZipInputStream(cipherInputStream);
ZipEntry nextEntry = zipInputStream.getNextEntry();
inputStream = zipInputStream;
if (nextEntry == null) {
System.out.println("error");
inputStream = null;
}
fileOutputStream = new FileOutputStream(fileName);
IOUtils.copy(inputStream, fileOutputStream);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
} else if (fileInputStream != null) {
fileInputStream.close();
} else if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Zipping a stream does not means that you create a zip file... If you want to create a zip file with a crypted file in it, you should create ZipEntry, add it to the ZipOutputStream and then push your encrypted data. You can have a look at http://www.oracle.com/technetwork/articles/java/compress-1565076.html wich is a good starting point.