【问题标题】:How do i decrypt a file in Android with AES?如何使用 AES 解密 Android 中的文件?
【发布时间】:2013-10-24 14:39:35
【问题描述】:

我有一个要加密的文件 (mp3),然后我打算将此文件下载到 Android 设备并对其进行解密,但在解密过程中我得到一个 IOException:

java.io.IOException: last block incomplete in decryption

我知道以下代码中存在明显的安全漏洞,我只是想先让它工作。

感谢您对此提供的任何帮助,而且我一般是编码新手,所以如果这是一个愚蠢的问题,请提前原谅!

加密类(Android 中没有,可以):

public class EncryptFile {
public static void main(String args[]) {
    if (args.length < 1) {
        System.out.println("Usage: java EncryptFile <file name>");
        System.exit(-1);
    }
    try {
        File aesFile = new File("encodedfile.enc");
        FileInputStream fis;
        FileOutputStream fos;
        CipherInputStream cis;
         //Creation of Secret key
        String key = "mysecretkey";
        int length=key.length();
        if(length>16 && length!=16){
            key=key.substring(0, 15);
        }
        if(length<16 && length!=16){
            for(int i=0;i<16-length;i++){
                key=key+"0";
            }
        }
        SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(),"AES");
         //Creation of Cipher objects
        Cipher encrypt =Cipher.getInstance("AES/CBC/PKCS5Padding");

        byte[] aByte = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};


            IvParameterSpec ivSpec = new IvParameterSpec(aByte);

        encrypt.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        try {
            fis = new FileInputStream(args[0]);
            cis = new CipherInputStream(fis,encrypt);
            // Write to the Encrypted file
            fos = new FileOutputStream(aesFile);
            byte[] b = new byte[8];
            int i = cis.read(b);
            while (i != -1) {
                fos.write(b, 0, i);
                i = cis.read(b);
            }
            fos.flush();
            fos.close();
            cis.close();
            fis.close();
        } catch(IOException err) {
            System.out.println("Cannot open file!");
            System.exit(-1);
        }
    } catch(Exception e){
        e.printStackTrace();
    }
}

}

解密(在 Android 设备中):

    public class DecryptFile {  
  public static File main(String args[], File encFile, Context context) { 
      for (int i = 0; i < args.length; i++) {
        Log.i("ARGS", args[i]);
    }
       try {  
            File aesFile = new File(args[0]);  

            aesFile= encFile;  
            Log.d("AESFILELENGTH", "aes length: " + aesFile.length());
            File aesFileBis = new File(context.getFilesDir(), args[0]);

            FileInputStream fis;  
            FileOutputStream fos;  
            CipherInputStream cis;  

 //Creation of Secret key  
            String key = "mysecretkey";  
            int length=key.length();  
            if(length>16 && length!=16){  
                 key=key.substring(0, 15);  
            }  
            if(length<16 && length!=16){  
                 for(int i=0;i<16-length;i++){  
                      key=key+"0";  
                 }  
            }  
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(),"AES");  
             //Creation of Cipher objects  
            Cipher decrypt =Cipher.getInstance("AES/CBC/PKCS5Padding");  

            byte[] aByte = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};


            IvParameterSpec ivSpec = new IvParameterSpec(aByte);

            decrypt.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);  

 // Open the Encrypted file  

            fis = new FileInputStream(aesFile);  

            cis = new CipherInputStream(fis, decrypt);  

            // Write to the Decrypted file  
            fos = new FileOutputStream(aesFileBis);  
            try {

                byte[] mByte = new byte[8];  
                int i = cis.read(mByte); 
                Log.i("MBYTE", "mbyte i: " + i);
                while (i != -1) {  
                    fos.write(mByte, 0, i);  
                    i = cis.read(mByte);  
                }  
            } catch (IOException e) {
                e.printStackTrace();
            }


            fos.flush();  
            fos.close();  
            cis.close();  
            fis.close(); 
            return aesFileBis;
       } catch(Exception e){  
            e.printStackTrace();  
       }
    return null;  
  }  
}

【问题讨论】:

  • 检查您正在生成的非 Android 加密文件的长度。将其与您在 Android 中读取的加密文件的长度进行比较。显然,这两个长度应该相同。如果不是,那么您可能有文件传输问题,而不是解密问题。
  • 我检查了文件长度,加密文件比原始文件大2个字节,但这是由于填充的原因吗?我还做了一个 byte[] mBytebase = Base64.encodeBase64(key.getBytes());并根据“重复”在我的 SecretKeySpec 中使用它。似乎没有任何帮助
  • 如你所说,填充将确保明文和加密文件的长度不同。您需要检查非 Android 和 Android 端的两个 加密 文件的长度是否相同。您需要确保两个系统之间的文件传输不会弄乱数据。
  • 啊对,抱歉误解了答案。现在我将加密文件放在资产中进行测试,所以传输不是问题

标签: java android aes encryption


【解决方案1】:

代码如下:

public class MainActivity extends Activity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);

          Button encryptButton = (Button) findViewById(R.id.button1);
          Button DecryptButton = (Button) findViewById(R.id.button2);
          encryptButton.setOnClickListener(new OnClickListener() {

                 @Override
                 public void onClick(View v) {
                       // TODO Auto-generated method stub
                       try {
                              encrypt();
                       } catch (InvalidKeyException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                       } catch (NoSuchAlgorithmException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                       } catch (NoSuchPaddingException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                       } catch (IOException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                       }
                 }
          });

          DecryptButton.setOnClickListener(new OnClickListener() {

                 @Override
                 public void onClick(View v) {
                       // TODO Auto-generated method stub
                       try {
                              decrypt();
                       } catch (InvalidKeyException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                       } catch (NoSuchAlgorithmException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                       } catch (NoSuchPaddingException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                       } catch (IOException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                       }
                 }
          });

   }

   /**
    * Here is Both function for encrypt and decrypt file in Sdcard folder. we
    * can not lock folder but we can encrypt file using AES in Android, it may
    * help you.
    *
    * @throws IOException
    * @throws NoSuchAlgorithmException
    * @throws NoSuchPaddingException
    * @throws InvalidKeyException
    */

   static void encrypt() throws IOException, NoSuchAlgorithmException,
                 NoSuchPaddingException, InvalidKeyException {
          // Here you read the cleartext.
          File extStore = Environment.getExternalStorageDirectory();
          FileInputStream fis = new FileInputStream(extStore + "/sampleFile");
          // This stream write the encrypted text. This stream will be wrapped by
          // another stream.
          FileOutputStream fos = new FileOutputStream(extStore + "/encrypted");

          // 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 {

          File extStore = Environment.getExternalStorageDirectory();
          FileInputStream fis = new FileInputStream(extStore + "/encrypted");

          FileOutputStream fos = new FileOutputStream(extStore + "/decrypted");
          SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(),
                       "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();
   }

} 

【讨论】:

  • 前段时间解决了,基本上我就是这样解决的,忘记更新我的答案,所以我将其标记为正确
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-22
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多