Java 如何加密SQLite数据库
你好,我对安卓系统还是有点陌生,我现在遇到了麻烦。我正在制作一个应用程序来保存我所有的在线帐户和密码,很简单,我想加密数据库。我目前正在尝试使用SQLCipher并开始阅读,但无论出于何种原因,我都无法正确实现它 我有.jar和.so,我确实将.jar文件添加到了库中。但是“import info.guardianproject.sqlite.SQLiteDatabase;”语句不起作用 我也已经在这个应用程序上使用了几个小时,现在我已经筋疲力尽了,这可能是战斗的一半Java 如何加密SQLite数据库,java,android,sqlite,encryption,Java,Android,Sqlite,Encryption,你好,我对安卓系统还是有点陌生,我现在遇到了麻烦。我正在制作一个应用程序来保存我所有的在线帐户和密码,很简单,我想加密数据库。我目前正在尝试使用SQLCipher并开始阅读,但无论出于何种原因,我都无法正确实现它 我有.jar和.so,我确实将.jar文件添加到了库中。但是“import info.guardianproject.sqlite.SQLiteDatabase;”语句不起作用 我也已经在这个应用程序上使用了几个小时,现在我已经筋疲力尽了,这可能是战斗的一半 import info.g
import info.guardianproject.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.content.Context;
import android.content.ContentValues;
import android.database.Cursor;
public class PasswordDatabaseHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
public static String TABLE;
public static final String COLUMN_ID = "_id";
public static final String COLUMN_WEBSITE = "website";
public static final String COLUMN_ACCOUNT = "account";
public static final String COLUMN_PASS = "password";
public PasswordDatabaseHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name + ".db", factory, DATABASE_VERSION);
TABLE = name;
}
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_TABLE = "CREATE TABLE " + TABLE + "(" + COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_WEBSITE + " TEXT," + COLUMN_ACCOUNT + " TEXT," + COLUMN_PASS + " TEXT" + ")";
db.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE);
onCreate(db);
}
public boolean checkAccount(String website, String account) {
String query = "Select * FROM " + TABLE + " WHERE " + COLUMN_WEBSITE + " = \"" + website + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
boolean flag = false;
if (cursor.moveToFirst()) {
cursor.moveToFirst();
if(cursor.getString(1).equals(website) && cursor.getString(2).equals(account))
flag = true;
} else {
flag = false;
}
cursor.close();
db.close();
return flag;
}
public void addAccount(String website, String account, String pass) {
ContentValues values = new ContentValues();
values.put(COLUMN_WEBSITE, website);
values.put(COLUMN_ACCOUNT, account);
values.put(COLUMN_PASS, pass);
SQLiteDatabase db = this.getWritableDatabase();
db.insert(TABLE, null, values);
db.close();
}
public String lookupAccount(String website, String account) {
String query = "Select * FROM " + TABLE + " WHERE " + COLUMN_WEBSITE + " = \"" + website + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
String info = "";
if (cursor.moveToFirst()) {
cursor.moveToFirst();
if(cursor.getString(2).equals(account)) {
info += website + " Account: " + account + " Password: " + cursor.getString(3) + "\n";
cursor.close();
}
else{
info = null;
}
}
else {
info = null;
}
cursor.close();
db.close();
return info;
}
public boolean removeAccount(String website, String account) {
boolean result = false;
String query = "Select * FROM " + TABLE + " WHERE " + COLUMN_WEBSITE + " = \"" + website + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
if (cursor.moveToFirst()) {
if(cursor.getString(2).equals(account)) {
db.delete(TABLE, COLUMN_ID + " = ?", new String[]{String.valueOf(Integer.parseInt(cursor.getString(0)))});
cursor.close();
result = true;
}
}
cursor.close();
db.close();
return result;
}
public boolean updateAccount(String website, String account, String pass) {
String clCommand = "Select * FROM " + TABLE + " WHERE " + COLUMN_WEBSITE + " = \"" + website + "\"";
SQLiteDatabase dataWriter = this.getWritableDatabase();
Cursor cursor = dataWriter.rawQuery(clCommand, null);
boolean updateOK = false;
if (cursor.moveToFirst()) {
cursor.moveToFirst();
ContentValues values = new ContentValues();
values.put(COLUMN_WEBSITE, website);
values.put(COLUMN_ACCOUNT, account);
values.put(COLUMN_PASS, pass);
dataWriter.update(TABLE, values, COLUMN_ID + " = ?", new String[] { String.valueOf(Integer.parseInt(cursor.getString(0))) });
updateOK = true;
} else {
updateOK = false;
}
dataWriter.close();
cursor.close();
return updateOK;
}
}
这是我创建的一个类,用来处理与数据库有关的所有事情,而不是一个活动
编辑**
有一个登录到这个应用程序的pin码,那个pin码就是我要用来解密的。如果忘记了此pin,您可以通过电子邮件将其发送到登录电子邮件。AES128如何
package com.test.util;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class AesUtil {
public static String key = "0000000000000090";
/**
* hex to byte[] : 16dd
* @param hex hex string
* @return
*/
public static byte[] hexToByteArray(String hex) {
if (hex == null || hex.length() == 0) {
return null;
}
byte[] ba = new byte[hex.length() / 2];
for (int i = 0; i < ba.length; i++) {
ba[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
}
return ba;
}
/**
* byte[] to hex : unsigned byte
*
* @param ba byte[]
* @return
*/
public static String byteArrayToHex(byte[] ba) {
if (ba == null || ba.length == 0) {
return null;
}
StringBuffer sb = new StringBuffer(ba.length * 2);
String hexNumber;
for (int x = 0; x < ba.length; x++) {
hexNumber = "0" + Integer.toHexString(0xff & ba[x]);
sb.append(hexNumber.substring(hexNumber.length() - 2));
}
return sb.toString();
}
/**
* AES
*
* @param message
* @return
* @throws Exception
*/
public static String encrypt(String message) throws Exception {
//KeyGenerator kgen = KeyGenerator.getInstance("AES");
//kgen.init(128);
// use key coss2
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
// Instantiate the cipher
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(message.getBytes());
return byteArrayToHex(encrypted);
}
/**
* AES
*
* @param message
* @return
* @throws Exception
*/
public static String decrypt(String encrypted) throws Exception {
//KeyGenerator kgen = KeyGenerator.getInstance("AES");
//kgen.init(128);
// use key coss2
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] original = cipher.doFinal(hexToByteArray(encrypted));
String originalString = new String(original);
return originalString;
}
}
package com.test.util;
导入javax.crypto.Cipher;
导入javax.crypto.spec.SecretKeySpec;
公共类AesUtil{
公共静态字符串key=“00000000000000 90”;
/**
*十六进制到字节[]:16dd
*@param十六进制字符串
*@返回
*/
公共静态字节[]十六进制字节数组(字符串十六进制){
如果(hex==null | | hex.length()==0){
返回null;
}
byte[]ba=新字节[hex.length()/2];
for(int i=0;i
不确定这样做是否值得。你要把解密密钥放在哪里?攻击者可以反编译您的应用程序并获取密钥。混淆可能会使其更加困难,但并非不可能。如果您将密钥保留在web服务中,则需要将身份验证凭据存储在应用程序中,这样只需添加一个步骤。如果您试图防范的攻击者是用户,我会放弃它。如果它是一个恶意应用程序,我会依靠系统安全保护数据库文件不被其他应用程序访问。我想我应该检查一下,有一个登录到这个应用程序的pin码,该pin码就是我要用来解密的。如果忘记了此pin,您可以将其通过电子邮件发送到登录电子邮件。因此,用户每次输入pin进行解密时,它都不会被保存?听起来很合理。不过,我从来没有在Android上做过加密,所以我想我在这方面帮不了你,对不起。但你的问题并没有真正说明问题所在。到底是什么东西不起作用,以及如何起作用?问题是如何实现加密。我似乎无法让图书馆正常工作。我添加了一些,因为通过JavaSQLite进行加密显然需要某种许可证。至少这是我读到的。所以在我的情况下,我会使用这个类在输入字符串之前对我放入数据库的字符串进行加密?非常感谢!因为我使用了这种加密数据的方法,而不是数据库,所以我能够整合到一个数据库,而不是每个用户一个!再次感谢