尝试解密文件时出现错误

时间:2018-12-27 02:33:21

标签: java encryption

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();
        }
    }

错误:

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)

您好,我尝试加密一个文件,该文件可以是文本文件或音乐文件等。程序有点对它进行加密,但是,当我尝试解密时,它会引发异常。 我一直在尝试使用CBC模式使其运行几天,现在有人可以指出我的错误吗?

嗯,我实际上是在Android设备上运行它,所以我在SO上发布时用“ c:”更改了根部分,所以发布的错误与从A.S上的调试器控制台获得的错误相同。

我是Java的新手,只是在我的学习上有所进步,因此可以提供任何帮助。谢谢。

1 个答案:

答案 0 :(得分:1)

请注意,对于每个加密,实际代码均应使用非秘密的随机IV,而不是固定的秘密IV。密码应使用密码哈希功能来构成密钥。为此,可以在Android和Java上使用PBKDF2。

您的代码有很多问题:

  • 您每次通过循环都在呼叫Cipher.doFinal()。结合固定的IV,结果实际上等效于ECB模式,因此是不安全的。对所有中间块使用Cipher.update(),直到最后一个块,然后调用Cipher.doFinal()
  • 每次向inBytes读取少于完整缓冲区的数据时,您将提供无效数据以进行加密和解密。
  • count是读入的字节数,不一定是encrypted的大小。您应该准确输出encrypted的内容,而不是其中的一部分。
  • 您的主要方法是对PATH处的文件进行加密,然后将结果写入c:/logs1/PATH。然后,它尝试解密PATH处的文件,但该文件是纯文本文件,而不是密文文件。

以下是经过纠正的encryptdecrypt方法:

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;
}