2014-09-21 195 views
0

我想加密我的python web服務器中的一些文件,並在下載後在android應用程序中解密它們。我使用python AES encryption java decryption這樣的問題方法,但我得到了Android代碼中的填充異常我該怎麼辦? 我的Python代碼:加密python文件和解密在android

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

key = 'abcdef' 
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

如果你投下來,請告訴我爲什麼? – 2014-09-21 10:06:38

+0

爲什麼不發佈實際的異常棧跟蹤?另外,你有一個或兩個問題嗎? – 2014-09-21 12:36:27

+0

python代碼太糟糕了。但除此之外,它使用自己的本地填充方案,當然這與其他任何方面都不兼容。 – 2014-09-21 13:26:29

回答

0

你從這個question複製的python代碼真的不適合任何東西。它執行填充作爲硬編碼常量CHUNKSIZE爲16的倍數的副作用。如果由於某種原因,您不知道這一點,並將CHUNKSIZE更改爲1000,則該代碼將以難以理解的方式失敗。

python代碼使用的填充也是非標準的。要使用像PKCS5/7填充這樣的標準,請參閱this答案。