aloy
aloy

Reputation: 53

Getting errors when trying to decrypt a file

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

Answers (1)

President James K. Polk
President James K. Polk

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:

  • You're calling 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().
  • You're supplying invalid data to encrypt and decrypt every time you read less than a full buffer into 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.
  • You main method encrypts a file at 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

Related Questions