在python中加密文件并在android中解密

时间:2014-09-21 06:25:24

标签: java android python encryption cryptography

我正在尝试加密我的python Web服务器中的一些文件,并在下载后在android应用程序中解密它们。我使用了python AES encryption java decryption这样的问题方法但我在android代码中得到了填充异常我该怎么办? 我的python代码:

from Crypto.Cipher import AES
import os, random, struct

key = '0123456789abcdef'
mode = AES.MODE_CBC
chunksize = 64*1024

iv = ''.join(chr(random.randint(0,0xFF)) for i in range(16))
encryptor = AES.new(key,mode,iv)
filesize = os.path.getsize('sample.jpg')

with open('sample.jpg','rb') as infile:
    with open('sample.enc','wb') as outfile:
        outfile.write(struct.pack('<Q',filesize))
        outfile.write(iv)

        while True:
            chunk = infile.read(chunksize)
            if len(chunk) == 0:
                break
            elif len(chunk) % 16 != 0:
                chunk += ' ' * (16 - len(chunk) % 16)

            outfile.write(encryptor.encrypt(chunk))

## decrypt
with open('sample.enc', 'rb') as infile:
    origsize = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
    iv = infile.read(16)
    print('test',iv.hexdigest())
    decryptor = AES.new(key, AES.MODE_CBC, iv)
    with open('sample2.jpg', 'wb') as outfile:
        while True:
            chunk = infile.read(chunksize)
            if len(chunk) == 0:
                break
            outfile.write(decryptor.decrypt(chunk))
        outfile.truncate(origsize)

和android代码:

package com.example.crypto;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.os.Build;

public class MainActivity extends ActionBarActivity {

   @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();
                    }
              }
       });
 public void decryptFile(){

       String inFile = "sample.enc";
       String outFile = "sample.jpg";
       String dir = Environment.getExternalStorageDirectory() +"/Books/";
       InputStream is = null ;

       byte[] filesize = new byte[8];
       byte[] iv = new byte[16];
       try {
           is = new FileInputStream(dir+inFile);

           is.read(filesize);
           is.read(iv);

       } catch (FileNotFoundException e1) {
           // TODO Auto-generated catch block
           Log.d("D1","no file found");
       } catch (IOException e) {
           // TODO Auto-generated catch block
           Log.d("D-2","no file found");
           e.printStackTrace();
       }

       byte[] k = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

       Key key = new SecretKeySpec(k,"AES");




       try {
           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
           cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(iv));
           OutputStream outs = new FileOutputStream(dir+outFile);
           //is = new FileInputStream(dir+inFile);

           while(true){
               byte[] chunk = new byte[64*1024];

               is.read(chunk);
               if(chunk.length == 0){

                   break;

               }
               outs.write(cipher.doFinal(chunk));              
           }


       } catch (NoSuchAlgorithmException e) {
           // TODO Auto-generated catch block
           Log.d("D","1");

           e.printStackTrace();
       } catch (NoSuchPaddingException e) {
           // TODO Auto-generated catch block
           Log.d("D","2");
           e.printStackTrace();
       } catch (InvalidKeyException e) {
           // TODO Auto-generated catch block
           Log.d("D","3");
           e.printStackTrace();
       } catch (InvalidAlgorithmParameterException e) {
           // TODO Auto-generated catch block
           Log.d("D","4");
           e.printStackTrace();
       } catch (FileNotFoundException e) {
           // TODO Auto-generated catch block
           Log.d("D","5");
           e.printStackTrace();
       } catch (IOException e) {
           // TODO Auto-generated catch block
           Log.d("D","6");
           e.printStackTrace();
       } catch (IllegalBlockSizeException e) {
           // TODO Auto-generated catch block
           Log.d("D","7");
           e.printStackTrace();
       } catch (BadPaddingException e) {
           // TODO Auto-generated catch block
           Log.d("D","8");
           e.printStackTrace();
       }


   }

我在基本代码中修复了一些错误,如文件大小和...但仍存在填充问题。在python中解密我们使用文件大小并截断文件,但在java中我不知道如何做到这一点!

1 个答案:

答案 0 :(得分:0)

你从这个question复制的python代码真的不适合任何东西。它执行填充作为具有硬编码常量CHUNKSIZE为16的倍数的副作用。如果由于某种原因您不知道这并且将CHUNKSIZE更改为1000,则代码将以难以理解的方式失败。

python代码使用的填充也是非标准的。要使用像PKCS5 / 7填充这样的标准,请参阅this answer。