使用FileInputStream / Cipher在Android中加密/解密数据库文件

时间:2016-09-25 00:17:15

标签: android sqlite encryption cryptography

我使用Cipher / CipherInputStream加密和解密Android中的数据库文件(sqlite)以备份它。
当我使用没有Cipher的FileInputStream时,它运行得很好。但是当我使用Cipher时,文件会成功加密,但是当我解密(恢复)它时,数据库不会解密为原始的"源代码"。
原始的caracteres(源代码)似乎是一个表意文字/象形文字/ kanjis(我不知道),当我加密和解密时,"源代码"是sql(英文)恢复O.O
这会使数据库损坏'

仅澄清

备份

<?php if ($item->getParams()->get('image')) : ?>
  <img src="<?php echo $item->getParams()->get('image');?>" alt="">
<?php end if; ?>

还原:

 on CheckExistence(FileOrFolderToCheckString)
   try
       alias FileOrFolderToCheckString
       return true
   on error
       return false
   end try
end CheckExistence

1 个答案:

答案 0 :(得分:2)

CBC模式需要初始化矢量(IV)才能运行。这个IV不是秘密值,但它必须是不可预测的(读:随机选择)。为了使解密起作用,您必须使用相同的IV。否则,第一个块将被破坏。解决此问题的常用方法是在密文前面写入IV。

如果在没有IvParameterSpec作为第三个参数的情况下调用Cipher#init,将自动为您生成IV。如果你不存储它,它就会丢失。

加密期间

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, sks);

outputStream.write(cipher.getIV()); // store the generated IV

CipherOutputStream cos = new CipherOutputStream(outputStream, cipher);

解密期间

byte[] iv = new byte[16]; // 16 is the block size of AES
if (fis.read(iv) != 16) {
    throw new Exception("Incomplete IV"); // TODO: rename to a different exception
}

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, sks, new IvParameterSpec(iv));

CipherInputStream cis = new CipherInputStream (fis, cipher);