Android数据库文件加密/解密

时间:2013-10-17 11:18:44

标签: android encryption

在我的应用程序中使用敏感数据。我在assest文件夹中有我的初始数据库。当我将数据库复制到我需要解密的安装位置时,资产文件夹包含加密数据库。解密数据库时出现以下错误

     10-17 16:30:25.878: W/System.err(15231): java.io.IOException: pad block corrupted
10-17 16:30:25.889: W/System.err(15231):    at javax.crypto.CipherInputStream.read(CipherInputStream.java:102)
10-17 16:30:25.889: W/System.err(15231):    at javax.crypto.CipherInputStream.read(CipherInputStream.java:134)
10-17 16:30:25.898: W/System.err(15231):    at java.io.InputStream.read(InputStream.java:163)
10-17 16:30:25.898: W/System.err(15231):    at xont.virtusel.v4.controller.syn.DBEncript.ReadEncryptedFile(DBEncript.java:178)
10-17 16:30:25.898: W/System.err(15231):    at xont.virtusel.v4.controller.syn.DBEncript.callRead(DBEncript.java:247)
10-17 16:30:25.898: W/System.err(15231):    at xont.virtusel.v4.db.DataBaseHelper.extarctDataBase(DataBaseHelper.java:116)
10-17 16:30:25.898: W/System.err(15231):    at xont.virtusel.v4.db.DataBaseHelper.copyDataBase(DataBaseHelper.java:104)
10-17 16:30:25.908: W/System.err(15231):    at xont.virtusel.v4.db.DataBaseHelper.createDataBase(DataBaseHelper.java:59)
10-17 16:30:25.908: W/System.err(15231):    at xont.virtusel.v4.controller.syn.DatabaseSetupActivity$1.onItemClick(DatabaseSetupActivity.java:43)
10-17 16:30:25.908: W/System.err(15231):    at android.widget.AdapterView.performItemClick(AdapterView.java:292)
10-17 16:30:25.908: W/System.err(15231):    at android.widget.AbsListView.performItemClick(AbsListView.java:1058)
10-17 16:30:25.908: W/System.err(15231):    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2514)
10-17 16:30:25.908: W/System.err(15231):    at android.widget.AbsListView$1.run(AbsListView.java:3168)
10-17 16:30:25.908: W/System.err(15231):    at android.os.Handler.handleCallback(Handler.java:605)
10-17 16:30:25.908: W/System.err(15231):    at android.os.Handler.dispatchMessage(Handler.java:92)
10-17 16:30:25.919: W/System.err(15231):    at android.os.Looper.loop(Looper.java:137)
10-17 16:30:25.919: W/System.err(15231):    at android.app.ActivityThread.main(ActivityThread.java:4340)
10-17 16:30:25.919: W/System.err(15231):    at java.lang.reflect.Method.invokeNative(Native Method)
10-17 16:30:25.928: W/System.err(15231):    at java.lang.reflect.Method.invoke(Method.java:511)
10-17 16:30:25.928: W/System.err(15231):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
10-17 16:30:25.928: W/System.err(15231):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
10-17 16:30:25.928: W/System.err(15231):    at dalvik.system.NativeStart.main(Native Method)

我的代码与URL

相同
public class DBEncript {

    String mPassword = null;
    public final static int SALT_LEN = 8;
    byte [] mInitVec = null;
    byte [] mSalt = null;
    Cipher mEcipher = null;
    Cipher mDecipher = null;
    private final int KEYLEN_BITS = 128; // see notes below where this is used.
    private final int ITERATIONS = 65536;
    private final int MAX_FILE_BUF = 1024;

    public DBEncript (String password){
        mPassword = password;
    }

    public byte [] getSalt (){
        return (mSalt);
    }

    public byte [] getInitVec (){
        return (mInitVec);
    }

    private void Db (String msg){
        System.out.println ("** DBEncript ** " + msg);
    }

    /**
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws NoSuchPaddingException
     * @throws InvalidParameterSpecException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws UnsupportedEncodingException
     * @throws InvalidKeyException
     */
    public void setupEncrypt () throws NoSuchAlgorithmException, 
                                                           InvalidKeySpecException, 
                                                           NoSuchPaddingException, 
                                                           InvalidParameterSpecException, 
                                                           IllegalBlockSizeException, 
                                                           BadPaddingException, 
                                                           UnsupportedEncodingException, 
                                                           InvalidKeyException {
        SecretKeyFactory factory = null;
        SecretKey tmp = null;
        mSalt = new byte [SALT_LEN];
        SecureRandom rnd = new SecureRandom ();
        rnd.nextBytes (mSalt);
        Db ("generated salt :" + Hex.encodeHex (mSalt));

        factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

        KeySpec spec = new PBEKeySpec (mPassword.toCharArray (), mSalt, ITERATIONS, KEYLEN_BITS);
        tmp = factory.generateSecret (spec);
        SecretKey secret = new SecretKeySpec (tmp.getEncoded(), "AES");

        mEcipher = Cipher.getInstance ("AES/CBC/PKCS5Padding");
        mEcipher.init (Cipher.ENCRYPT_MODE, secret);
        AlgorithmParameters params = mEcipher.getParameters ();

        mInitVec = params.getParameterSpec (IvParameterSpec.class).getIV();

        Db ("mInitVec is :" + Hex.encodeHex (mInitVec));
    }

    public void setupDecrypt (String initvec, String salt) throws NoSuchAlgorithmException,InvalidKeySpecException,NoSuchPaddingException, 
                                                                                       InvalidKeyException,InvalidAlgorithmParameterException,DecoderException{
        SecretKeyFactory factory = null;
        SecretKey tmp = null;
        SecretKey secret = null;

        mSalt = Hex.decodeHex (salt.toCharArray ());
        Db ("got salt " + Hex.encodeHex (mSalt));

        mInitVec = Hex.decodeHex (initvec.toCharArray ());
        Db ("got initvector :" + Hex.encodeHex (mInitVec));


        factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(mPassword.toCharArray (), mSalt, ITERATIONS, KEYLEN_BITS);

        tmp = factory.generateSecret(spec);
        secret = new SecretKeySpec(tmp.getEncoded(), "AES");

        mDecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        mDecipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(mInitVec));
    }


    public void WriteEncryptedFile (File input, File output) throws IOException, IllegalBlockSizeException,BadPaddingException{
        FileInputStream fin;
        FileOutputStream fout;
        long totalread = 0;
        int nread = 0;
        byte [] inbuf = new byte [MAX_FILE_BUF];

        fout = new FileOutputStream (output);
        fin = new FileInputStream (input);

        while ((nread = fin.read (inbuf)) > 0 )
        {
           // Db ("read " + nread + " bytes");
            totalread += nread;
            byte [] trimbuf = new byte [nread];
            for (int i = 0; i < nread; i++)
                trimbuf[i] = inbuf[i];

            byte [] tmp = mEcipher.update (trimbuf);

            if (tmp != null)
                fout.write (tmp);
        }

        byte [] finalbuf = mEcipher.doFinal ();
        if (finalbuf != null)
            fout.write (finalbuf);

        fout.flush();
        fin.close();
        fout.close();
        fout.close ();

        Db ("wrote " + totalread + " encrypted bytes");
    }



    public void ReadEncryptedFile (File input, File output) throws IllegalBlockSizeException,BadPaddingException, IOException{

        FileInputStream fin; 
        FileOutputStream fout;
        CipherInputStream cin;
        long totalread = 0;
        int nread = 0;
        byte [] inbuf = new byte [MAX_FILE_BUF];

        fout = new FileOutputStream (output);
        fin = new FileInputStream (input);

        cin = new CipherInputStream (fin, mDecipher);
        while ((nread = cin.read (inbuf)) > 0 )
        {
            //Db ("read " + nread + " bytes");
            totalread += nread;

            byte [] trimbuf = new byte [nread];
            for (int i = 0; i < nread; i++)
                trimbuf[i] = inbuf[i];

            fout.write (trimbuf);
        }

        fout.flush();
        cin.close();
        fin.close ();       
        fout.close();   

    }


    public void callRead(File input, File output) {
        String iv = null;
        String salt = null;
        DBEncript en = new DBEncript ("123");
        try{
            en.setupEncrypt ();
            iv = new String(Hex.encodeHex(en.getInitVec())).toUpperCase ();
            salt = new String(Hex.encodeHex(en.getSalt())).toUpperCase ();
          }catch (InvalidKeyException e){
            e.printStackTrace();
          }catch (NoSuchAlgorithmException e){
            e.printStackTrace();
          }catch (InvalidKeySpecException e){
            e.printStackTrace();
          }catch (NoSuchPaddingException e){
            e.printStackTrace();
          }catch (InvalidParameterSpecException e){
            e.printStackTrace();
          }catch (IllegalBlockSizeException e){
            e.printStackTrace();
          }catch (BadPaddingException e){
            e.printStackTrace();
          }catch (UnsupportedEncodingException e){
            e.printStackTrace();
          }


          /*
           * decrypt file
           */
          DBEncript dc = new DBEncript ("123");
          try{
            dc.setupDecrypt (iv, salt);
          }catch (InvalidKeyException e){
            e.printStackTrace();
          }catch (NoSuchAlgorithmException e){
            e.printStackTrace();
          }catch (InvalidKeySpecException e){
            e.printStackTrace();
          }catch (NoSuchPaddingException e){
            e.printStackTrace();
          }catch (InvalidAlgorithmParameterException e){
            e.printStackTrace();
          }catch (DecoderException e){
            e.printStackTrace();
          }


          try{
              dc.ReadEncryptedFile (input, output);
              System.out.println ("decryption finished to " + output.getName ());
            }catch (IllegalBlockSizeException e){
              e.printStackTrace();
            }catch (BadPaddingException e){
              e.printStackTrace();
            }catch (IOException e){
              e.printStackTrace();
            }
    }



}

修改 这是我的召唤地点:

  private void extarctDataBase() throws IOException {
    // Open your local db as the input stream
    String outFileName = DB_PATH + DB_NAME;
    String extFileName = DB_PATH + SEC_NAME;
    DBEncript dc = new DBEncript ("xont@123");
    File eoutput = new File (extFileName);
    File doutput = new File (outFileName);
    System.out.println("==START===");
    dc.callRead(eoutput, doutput);
    System.out.println ("decryption finished to " + doutput.getName ());

}

1 个答案:

答案 0 :(得分:1)

更改此

mDecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

mDecipher = Cipher.getInstance("AES/CFB8/NoPadding");

你应该为mEcipher做同样的事。