Android использует базу данных SQLite для хранения данных, мне нужно зашифровать базу данных SQLite, как это можно сделать? Я понимаю, что данные приложения являются конфиденциальными. Однако мне нужно явно зашифровать базу данных SQLite, которую использует мое приложение.
источник
Базы данных зашифрованы для предотвращения
INDIRECT ATTACKS
. Этот термин и классы: KeyManager.java , Crypto.java взяты из книги Шерана Гунасекера « Безопасность приложений Android» . Всю эту книгу рекомендую к прочтению.INDIRECT ATTACKS
названы так, потому что вирус не преследует ваше приложение напрямую. Вместо этого он идет после ОС Android. Цель состоит в том, чтобы скопировать все базы данных SQLite в надежде, что автор вируса сможет скопировать любую конфиденциальную информацию, хранящуюся в них. Однако если бы вы добавили еще один уровень защиты, автор вируса увидел бы только искаженные данные. Давайте создадим криптографическую библиотеку, которую мы сможем повторно использовать во всех наших приложениях. Начнем с создания краткого набора спецификаций:Использует симметричные алгоритмы: наша библиотека будет использовать симметричный алгоритм или блочный шифр для шифрования и дешифрования наших данных. Мы остановимся на AES, хотя мы сможем изменить это позже.
Использует фиксированный ключ: нам нужно иметь возможность включать ключ, который мы можем сохранить на устройстве, которое будет использоваться для шифрования и дешифрования данных.
Ключ хранится на устройстве: ключ будет находиться на устройстве. Хотя это риск для нашего приложения с точки зрения прямых атак, этого должно быть достаточно для защиты от косвенных атак.
Начнем с нашего модуля управления ключами (см. Листинг 1 ). Поскольку мы планируем использовать фиксированный ключ, нам не нужно будет генерировать случайный ключ, как мы это делали в прошлых примерах. KeyManager будет выполнять следующие задачи:
setId(byte[] data)
метод)setIv(byte[] data)
метод)getId(byte[] data)
метод)getIv(byte[] data)
метод)(Листинг 1. Модуль KeyManager KeyManager.java )
Далее мы выполняем модуль Crypto (см. Листинг 2 ). Этот модуль заботится о шифровании и расшифровке. Мы добавили
armorEncrypt()
иarmorDecrypt()
метод к модулю , чтобы сделать его проще для преобразования данных байтового массива в печать Base64 данных , и наоборот. Мы будем использовать алгоритм AES с режимом шифрования Cipher Block Chaining (CBC) и заполнением PKCS # 5 .(Листинг 2. Криптографический модуль Crypto.java )
Вы можете включить эти два файла в любое из ваших приложений, требующих шифрования хранилища данных. Во-первых, убедитесь, что у вас есть значение для вашего ключа и вектора инициализации, затем вызовите любой из методов шифрования или дешифрования ваших данных перед их сохранением. Листинг 3 и 4 приведен простой пример использования этих классов в приложении. Мы создаем Activity с 3 кнопками Encrypt, Decrypt, Delete; 1 EditText для ввода данных; 1 TextView для вывода данных.
(Листинг 3. Пример. MainActivity.java )
package com.yourapp.android.crypto; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity { TextView encryptedDataView; EditText editInputData; private Context cntx; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.cntx = getApplicationContext(); Button btnEncrypt = (Button) findViewById(R.id.buttonEncrypt); Button btnDecrypt = (Button) findViewById(R.id.buttonDecrypt); Button btnDelete = (Button) findViewById(R.id.buttonDelete); editInputData = (EditText)findViewById(R.id.editInputData) ; encryptedDataView = (TextView) findViewById(R.id.encryptView); /**********************************************/ /** INITIALIZE KEY AND INITIALIZATION VECTOR **/ String key = "12345678909876543212345678909876"; String iv = "1234567890987654"; KeyManager km = new KeyManager(getApplicationContext()); km.setIv(iv.getBytes()); km.setId(key.getBytes()); /**********************************************/ btnEncrypt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String Data = editInputData.getText().toString(); String Encrypted_Data = "data"; try { Crypto crypto = new Crypto(cntx); Encrypted_Data = crypto.armorEncrypt(Data.getBytes()); } catch (InvalidKeyException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } catch (NoSuchAlgorithmException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } catch (NoSuchPaddingException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } catch (IllegalBlockSizeException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } catch (BadPaddingException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } catch (InvalidAlgorithmParameterException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } encryptedDataView.setText(Encrypted_Data); } }); btnDecrypt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String Data = encryptedDataView.getText().toString(); String Decrypted_Data = "data"; try { Crypto crypto = new Crypto(cntx); Decrypted_Data = crypto.armorDecrypt(Data); } catch (InvalidKeyException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } catch (NoSuchAlgorithmException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } catch (NoSuchPaddingException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } catch (IllegalBlockSizeException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } catch (BadPaddingException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } catch (InvalidAlgorithmParameterException e) { Log.e("SE3", "Exception in StoreData: " + e.getMessage()); } encryptedDataView.setText(Decrypted_Data); } }); btnDelete.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { encryptedDataView.setText(" Deleted "); } }); } }
(Листинг 4. Пример. Activity_main.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#363636" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <EditText android:id="@+id/editInputData" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:ems="10" android:textColor="#FFFFFF" > <requestFocus /> </EditText> <TextView android:id="@+id/encryptView" android:layout_width="fill_parent" android:layout_height="100dp" android:layout_alignLeft="@+id/editInputData" android:layout_alignRight="@+id/editInputData" android:layout_below="@+id/buttonEncrypt" android:layout_marginTop="26dp" android:background="#000008" android:text="Encrypted/Decrypted Data View" android:textColor="#FFFFFF" android:textColorHint="#FFFFFF" android:textColorLink="#FFFFFF" /> <Button android:id="@+id/buttonEncrypt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/encryptView" android:layout_alignRight="@+id/editInputData" android:layout_below="@+id/editInputData" android:layout_marginTop="26dp" android:text="Encrypt" /> <Button android:id="@+id/buttonDelete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/buttonDecrypt" android:layout_alignRight="@+id/buttonDecrypt" android:layout_below="@+id/buttonDecrypt" android:layout_marginTop="15dp" android:text="Delete" /> <Button android:id="@+id/buttonDecrypt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/encryptView" android:layout_alignRight="@+id/encryptView" android:layout_below="@+id/encryptView" android:layout_marginTop="21dp" android:text="Decrypt" /> </RelativeLayout>
источник
Если база данных будет небольшой, вы можете получить небольшую степень безопасности, расшифровав весь файл во временное место (не на SD-карту), а затем повторно зашифруя его, когда вы его закроете. Проблемы: преждевременная смерть приложения, фантомное изображение на носителе.
Немного лучшее решение для шифрования полей данных. Это вызывает проблему для предложений WHERE и ORDER BY. Если зашифрованные поля необходимо проиндексировать для поиска эквивалентности, вы можете сохранить криптографический хэш поля и выполнить поиск по нему. Но это не помогает при поиске по диапазону или упорядочивании.
Если вы хотите стать более интересным, вы можете углубиться в Android NDK и взломать криптовалюту в код C для SQLite.
Учитывая все эти проблемы и частичные решения, уверены ли вы, что вам действительно нужна база данных SQL для приложения? Возможно, вам лучше будет что-то вроде файла, содержащего зашифрованный сериализованный объект.
источник
Вы, безусловно, можете иметь зашифрованную базу данных SQLite на Android. Однако вы не можете сделать это с помощью готовых классов, предоставленных Google.
Пара альтернатив:
источник
http://sqlite-crypt.com/ может помочь вам создать зашифрованную базу данных, хотя я никогда не использовал ее на android, похоже, это возможно с исходным кодом.
источник