Reputation: 53
package test;
/**
* Created by
* newbme on 12/25/2018.
*/
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class MyJava {
/**
* IT IS THIS CLASS THAT WILL ENCRYPT OR DECRYPT
* ANY FILE
*/
private static final String SECRET_KEY_1 = "ssdkF$HUy2A#D%kd";
private static final String SECRET_KEY_2 = "weJiSEvR5yAC5ftB";
private IvParameterSpec ivParameterSpec;
private SecretKeySpec secretKeySpec;
private Cipher cipher;
private File from,to;
private static boolean trouble =false;
/**
* CBC MODE
*/
public MyJava(File from,File to) throws UnsupportedEncodingException, NoSuchPaddingException, NoSuchAlgorithmException {
ivParameterSpec = new IvParameterSpec(SECRET_KEY_1.getBytes("UTF-8"));
secretKeySpec = new SecretKeySpec(SECRET_KEY_2.getBytes("UTF-8"), "AES");
cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
//INITIALIZE THE PLACE TO READ AND SAVE FILE
this.from =from;
this.to =to;
//if the desination doesnt exists create it
if(! this.to .exists()){
try {
this.to.getParentFile().mkdirs();
this.to.createNewFile();
}catch (Exception ex){
ex.printStackTrace();
}
}
}
/**
*
* USE THIS METHOD TO ENCRYPT ANYTHING
*/
public boolean encrypt()throws Exception{
FileInputStream fis =null;
FileOutputStream fos=null;
boolean success =false;
try {
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
//read the file into memory
fis = new FileInputStream(from);
fos = new FileOutputStream(to);
byte [] inBytes = new byte[50*1024];
int count;
while( ( count = fis.read(inBytes)) > 0){
byte encrypted[] = cipher.doFinal(inBytes);
fos.write(encrypted,0,count);
fos.flush();
}
success =true;
}catch(InvalidKeyException ivke){
ivke.printStackTrace();
trouble = true;
}finally{
if(fis!=null)fis.close();
if(fos!=null)fos.close();
}
//return Base64.encodeBase64String(encrypted);
return success;
}
/**
*
* USE THIS METHOD TO DECRYPT ANYTHING
*/
public boolean decrypt() throws Exception{
FileInputStream fis =null;
FileOutputStream fos=null;
boolean success =false;
try {
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
//read the file into memory
fis = new FileInputStream(from);
fos = new FileOutputStream(to);
byte [] inBytes = new byte[50*1024];
int count;
while( ( count = fis.read(inBytes)) > 0){
byte decrypted[] = cipher.doFinal(inBytes);//this line fails
fos.write(decrypted,0,count);
fos.flush();
}
success =true;
}catch(InvalidKeyException ivke){
trouble = true;
ivke.printStackTrace();
}finally{
if(fis!=null)fis.close();
if(fos!=null)fos.close();
}
//return Base64.encodeBase64String(encrypted);
return success;
}
private static boolean isInvalidKeyException(){
return trouble;
}
public static void main(String [] R){
File f = new File(PATH);
//encrypt
new MyJava(f,new File("c:/logs1/"+f.getName())).encrypt();
//Toast.makeText(context,"to decrypt",Toast.LENGTH_LONG).show();
//decrypt
new MyJava(f,new File("c:/logs2/"+f.getName())).decrypt();
}
}
Error:
D/OpenSSLLib: OpensslErr:Module:30(101:); file:external/boringssl/src/crypto/cipher/cipher.c ;Line:460;Function:EVP_DecryptFinal_ex
W/System.err: javax.crypto.BadPaddingException: error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT
W/System.err: at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
W/System.err: at com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER.doFinalInternal(OpenSSLCipher.java:568)
W/System.err: at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:350)
W/System.err: at javax.crypto.Cipher.doFinal(Cipher.java:2056)
W/System.err: at com.presentapps.aiapp.utility.AISCipher.decrypt(AISCipher.java:122)
W/System.err: at com.presentapps.aiapp.popups.ActionPop$1.onClick(ActionPop.java:65)
Hello, I tried to encrypt a file which could be a text file or a music file etc. The program kinda encrypts it without any exception, however when I try to decrypt, it throws an exception. I've been trying to use CBC mode to get it working for days now, could someone help point out my errors?
And uhm, I am actually running it on Android device so I changed the root part with "c:" while posting on SO the error posted was same gotten from debugger console on A.S.
I'm a newb to java, just improving on my learning, so any help is appreciated. Thanks.
Upvotes: 0
Views: 485
Reputation: 41974
Please note that real code should use a non-secret random IV for each encryption rather than a fixed, secret IV. Passwords should use a password-hashing function to make into keys. PBKDF2 is available on Android and Java for this purpose.
There are a number of problems with your code:
Cipher.doFinal()
every time through the loop. Combined with a fixed IV, the result is effectively equivalent to ECB mode and is thus insecure. Use Cipher.update()
for all intermediate blocks until the final block, then call Cipher.doFinal()
.inBytes
.count
is the number of bytes that were read in, not necessarily the size of encrypted
. You should output exactly the contents of encrypted
, not some piece of it.PATH
and writes the result to c:/logs1/PATH
. It then attempts to decrypt the file at PATH
, but that file is the plaintext file, not the cipher text file.Here are the corrected encrypt
and decrypt
methods:
public boolean encrypt() throws Exception {
FileInputStream fis = null;
FileOutputStream fos = null;
boolean success = false;
try {
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
//read the file into memory
fis = new FileInputStream(from);
fos = new FileOutputStream(to);
byte[] inBytes = new byte[50 * 1024];
int count;
while ((count = fis.read(inBytes)) > 0) {
byte encrypted[] = cipher.update(inBytes, 0, count);
fos.write(encrypted);
}
byte encrypted[] = cipher.doFinal();
fos.write(encrypted);
fos.flush(); // redundant, since closing the stream will flush it.
success = true;
} catch (InvalidKeyException ivke) {
ivke.printStackTrace();
trouble = true;
} finally {
if (fis != null) fis.close();
if (fos != null) fos.close();
}
//return Base64.encodeBase64String(encrypted);
return success;
}
public boolean decrypt() throws Exception {
FileInputStream fis = null;
FileOutputStream fos = null;
boolean success = false;
try {
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
//read the file into memory
fis = new FileInputStream(from);
fos = new FileOutputStream(to);
byte[] inBytes = new byte[50 * 1024];
int count;
while ((count = fis.read(inBytes)) > 0) {
byte decrypted[] = cipher.update(inBytes, 0, count);
fos.write(decrypted);
}
byte decrypted[] = cipher.doFinal();
fos.write(decrypted);
fos.flush();
success = true;
} catch (InvalidKeyException ivke) {
trouble = true;
ivke.printStackTrace();
} finally {
if (fis != null) fis.close();
if (fos != null) fos.close();
}
//return Base64.encodeBase64String(encrypted);
return success;
}
Upvotes: 1