Android verwendet die SQLite-Datenbank zum Speichern von Daten. Ich muss die SQLite-Datenbank verschlüsseln. Wie kann das gemacht werden? Ich verstehe, dass Anwendungsdaten privat sind. Ich muss jedoch die von meiner App verwendete SQLite-Datenbank explizit verschlüsseln.
android
database
sqlite
encryption
user121196
quelle
quelle
Datenbanken werden verschlüsselt, um dies zu verhindern
INDIRECT ATTACKS
. Dieser Begriff und die Klassen: KeyManager.java , Crypto.java stammen aus dem Buch Android Apps Security von Sheran Gunasekera . Ich empfehle das ganze Buch zum Lesen.INDIRECT ATTACKS
sind so benannt, weil der Virus nicht direkt nach Ihrer Anwendung geht. Stattdessen geht es nach dem Android-Betriebssystem. Ziel ist es, alle SQLite-Datenbanken in der Hoffnung zu kopieren, dass der Virenautor alle dort gespeicherten vertraulichen Informationen kopieren kann. Wenn Sie jedoch eine weitere Schutzschicht hinzugefügt hätten, würde der Virenautor nur verstümmelte Daten sehen. Erstellen wir eine kryptografische Bibliothek, die wir in allen unseren Anwendungen wiederverwenden können. Beginnen wir mit der Erstellung eines kurzen Satzes von Spezifikationen:Verwendet symmetrische Algorithmen: Unsere Bibliothek verwendet einen symmetrischen Algorithmus oder eine Blockverschlüsselung, um unsere Daten zu verschlüsseln und zu entschlüsseln. Wir werden uns für AES entscheiden, obwohl wir dies zu einem späteren Zeitpunkt ändern können sollten.
Verwendet einen festen Schlüssel: Wir müssen in der Lage sein, einen Schlüssel einzuschließen, den wir auf dem Gerät speichern können, der zum Ver- und Entschlüsseln von Daten verwendet wird.
Auf dem Gerät gespeicherter Schlüssel: Der Schlüssel befindet sich auf dem Gerät. Dies ist zwar ein Risiko für unsere Anwendung aus Sicht direkter Angriffe, sollte jedoch ausreichen, um uns vor indirekten Angriffen zu schützen.
Beginnen wir mit unserem Schlüsselverwaltungsmodul (siehe Listing 1 ). Da wir einen festen Schlüssel verwenden möchten, müssen wir nicht wie in den vorherigen Beispielen einen zufälligen Schlüssel generieren. Der KeyManager führt daher folgende Aufgaben aus:
setId(byte[] data)
Methode)setIv(byte[] data)
Methode)getId(byte[] data)
Methode)getIv(byte[] data)
Methode)(Listing 1. Das KeyManager-Modul KeyManager.java )
Als nächstes machen wir das Crypto- Modul (siehe Listing 2 ). Dieses Modul kümmert sich um die Ver- und Entschlüsselung. Wir haben dem Modul eine
armorEncrypt()
und-armorDecrypt()
Methode hinzugefügt , um die Konvertierung der Byte-Array-Daten in druckbare Base64- Daten und umgekehrt zu vereinfachen . Wir werden den AES- Algorithmus mit CBC-Verschlüsselungsmodus (Cipher Block Chaining) und PKCS # 5-Padding verwenden .(Listing 2. Das Kryptografiemodul Crypto.java )
Sie können diese beiden Dateien in jede Ihrer Anwendungen aufnehmen, für die die Verschlüsselung des Datenspeichers erforderlich ist. Stellen Sie zunächst sicher, dass Sie einen Wert für Ihren Schlüssel und Ihren Initialisierungsvektor haben, und rufen Sie dann eine der Verschlüsselungs- oder Entschlüsselungsmethoden für Ihre Daten auf, bevor Sie sie speichern. Listing 3 und Listing 4 enthalten ein einfaches App-Beispiel für diese Klassen. Wir erstellen eine Aktivität mit 3 Schaltflächen Verschlüsseln, Entschlüsseln, Löschen. 1 EditText für die Dateneingabe; 1 TextView für die Datenausgabe.
(Listing 3. Ein Beispiel. 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 "); } }); } }
(Listing 4. Ein Beispiel. 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>
quelle
Wenn die Datenbank klein ist, können Sie ein wenig Sicherheit gewinnen, indem Sie die gesamte Datei an einem temporären Speicherort (nicht auf einer SD-Karte) entschlüsseln und nach dem Schließen erneut verschlüsseln. Probleme: vorzeitiger App-Tod, Geisterbild auf Medien.
Eine etwas bessere Lösung zum Verschlüsseln der Datenfelder. Dies verursacht ein Problem für die WHERE- und ORDER BY-Klauseln. Wenn die verschlüsselten Felder für die Äquivalenzsuche indiziert werden müssen, können Sie einen kryptografischen Hash des Felds speichern und danach suchen. Dies hilft jedoch nicht bei der Bereichssuche oder -bestellung.
Wenn Sie schicker werden möchten, können Sie sich mit dem Android NDK befassen und Krypto in C-Code für SQLite hacken.
Sind Sie angesichts all dieser Probleme und Teillösungen sicher, dass Sie wirklich eine SQL-Datenbank für die Anwendung benötigen? Mit einer Datei, die ein verschlüsseltes serialisiertes Objekt enthält, sind Sie möglicherweise besser dran.
quelle
Sie können sicherlich eine verschlüsselte SQLite-Datenbank unter Android haben. Sie können dies jedoch nicht mit den von Google bereitgestellten Standardklassen tun.
Ein paar Alternativen:
quelle
http://sqlite-crypt.com/ kann Ihnen beim Erstellen einer verschlüsselten Datenbank helfen, obwohl ich sie noch nie auf Android verwendet habe. Dies scheint mit dem Quellcode möglich zu sein.
quelle