首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用FileInputStream/密码加密/解密Android中的数据库文件

用FileInputStream/密码加密/解密Android中的数据库文件
EN

Stack Overflow用户
提问于 2016-09-25 00:17:14
回答 1查看 1.2K关注 0票数 0

我使用密码/密码it加密和解密Android中的数据库文件(Sqlite)来备份它。

当我使用没有密码的FileInputStream时,它工作得很好。但是当我使用密码时,文件会成功地加密,但是当我解密(还原)它时,数据库不会解密到原始的“源代码”。

原始代码(源代码)似乎是表意文字/象形文字/汉字(我不知道),当我加密和解密时,“源代码”是sql(英语)还原的O.O。

使“数据库损坏”的

只是为了澄清

备份

代码语言:javascript
复制
File dbFile = new File(PATH_DB);

FileInputStream fileInputStream = new FileInputStream(PATH_DB);

FileOutputStream outputStream = new FileOutputStream(PATH_BKP);

byte[] s = Arrays.copyOf(KEY_DATABASE.getBytes(),16);
SecretKeySpec sks = new SecretKeySpec(s, "AES");

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

CipherOutputStream cos = new CipherOutputStream(outputStream, cipher);

//Transferencia dos dados do inputfile para o output
byte[] buffer = new byte[1024];
int length;
while ((length = fileInputStream.read(buffer))!= -1) {
    cos.write(buffer,0,length);
}

//Fecha as streams
cos.flush();
cos.close();
fileInputStream.close();

恢复:

代码语言:javascript
复制
FileInputStream fis = new FileInputStream(PATH_BKP);

FileOutputStream fos = new FileOutputStream(PATH_DB);

byte[] s = Arrays.copyOf(KEY_DATABASE.getBytes(),16);
SecretKeySpec sks = new SecretKeySpec(s, "AES");

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

CipherInputStream cis = new CipherInputStream (fis, cipher);

byte[] buffer = new byte[1024];
int length;
while ((length = cis.read(buffer)) != -1) {
    fos.write(buffer, 0, length);
}

fos.flush();
fos.close();
cis.close();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-25 07:57:45

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

如果您调用不带Cipher#init的IvParameterSpec作为第三个参数,则将自动为您生成IV。如果你不把它储存起来,它就会丢失。

加密期间

代码语言:javascript
复制
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);

解密期间

代码语言:javascript
复制
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);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39682186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档