sql >> Base de Datos >  >> RDS >> SQLite

Usando SQLCipher con Android

¿Cómo puedo integrar a la perfección SQLCipher con mi base de datos no cifrada existente, de modo que mi aplicación funcione como lo hace normalmente, pero ahora las bases de datos están cifradas?

tu no Entre otras cosas, debe ajustar su interfaz de usuario para solicitar al usuario una frase de contraseña y asegurarse de que puede solicitar esa frase de contraseña según sea necesario (por ejemplo, el usuario reanuda una tarea desde alguna actividad "interna", no solo cuando el usuario ejecuta su aplicación a través de un icono de lanzador).

Me gustaría un breve tutorial sobre esto

Primero, no es así como funciona Stack Overflow.

En segundo lugar, una cobertura decente de SQLCipher para Android requiere mucho más de lo que puede caber en una sola respuesta de desbordamiento de pila. Tengo un capítulo de 18 páginas sobre el tema en mi libro, por ejemplo. Esta respuesta ya es más larga que la gran mayoría de las preguntas de Android, y no culparía a las personas por cerrar esta pregunta por ser demasiado amplia.

¿Cómo debo verificar si la base de datos no está encriptada?

Intente abrirlo usando las clases SQLCipher para Android con "" como la frase de contraseña. Si se abre correctamente, la base de datos no está cifrada. Si eso falla, la base de datos está corrupta o encriptada, y sin la frase de contraseña adecuada, no puede notar la diferencia.

¿Cómo puedo encriptarlo?

El enfoque básico es:

  • Abra la base de datos sin cifrar

  • Usa el ATTACH Declaración SQL para adjuntar un archivo vacío para que sirva como la nueva base de datos cifrada, proporcionando la frase de contraseña deseada y nombrando la base de datos adjunta encrypted dentro de su sesión de base de datos

  • Ejecute SELECT sqlcipher_export('encrypted') en la base de datos abierta (sin cifrar), que exportará los datos de la base de datos sin cifrar a la cifrada (con la excepción de la versión del esquema de la base de datos, que se maneja en pasos posteriores)

  • Llame a getVersion() en la base de datos abierta (sin cifrar) y mantenga ese valor por un momento

  • Cierra la base de datos sin cifrar

  • Abra la base de datos encriptada, usando su frase de contraseña

  • Llame a setVersion() en la base de datos cifrada, proporcionando el valor que almacenó en caché desde getVersion() de la base de datos sin cifrar

  • Cierra la base de datos encriptada

  • Si lo desea, elimine la base de datos sin cifrar y cambie el nombre de la base de datos cifrada por el nombre de la base de datos sin cifrar ahora eliminada, para que su conversión parezca realizarse en su lugar

Este método de utilidad implementa el enfoque anterior:

  public static void encrypt(Context ctxt, String dbName,
                             String passphrase) throws IOException {
    File originalFile=ctxt.getDatabasePath(dbName);

    if (originalFile.exists()) {
      File newFile=
          File.createTempFile("sqlcipherutils", "tmp",
                              ctxt.getCacheDir());
      SQLiteDatabase db=
          SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(),
                                      "", null,
                                      SQLiteDatabase.OPEN_READWRITE);

      db.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';",
                                  newFile.getAbsolutePath(), passphrase));
      db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
      db.rawExecSQL("DETACH DATABASE encrypted;");

      int version=db.getVersion();

      db.close();

      db=
          SQLiteDatabase.openDatabase(newFile.getAbsolutePath(),
                                      passphrase, null,
                                      SQLiteDatabase.OPEN_READWRITE);
      db.setVersion(version);
      db.close();

      originalFile.delete();
      newFile.renameTo(originalFile);
    }
  }

En aras de la divulgación completa, no he probado esto por un tiempo, por lo que es posible que deba haber algunos ajustes.

¿Debo hacer esto solo una vez?

Solo tú puedes responder eso, ya que nadie aquí sabrá mucho sobre tu aplicación.

Cuando cifro mi base de datos no cifrada existente, ¿SQLCipher crea una nueva base de datos?

Sí.

En caso afirmativo, ¿cómo debo gestionar este nuevo?

Solo tú puedes responder eso, ya que nadie aquí sabrá mucho sobre tu aplicación.

¿Y qué pasa con mi antigua base de datos que no está cifrada? ¿Sigue ahí?

Sí, aunque puede eliminarlo cuando haya terminado con él.