【问题标题】:How can I export/import from the Room database to Storage?如何从 Room 数据库导出/导入到 Storage?
【发布时间】:2020-01-13 05:58:20
【问题描述】:

我想将我的数据库数据存储在一个文件中并对其进行加密,并在导入文件时询问用户密码是否正确。

几乎像这个应用程序: https://www.youtube.com/watch?v=2p8H67PuiAU

【问题讨论】:

    标签: java android android-studio android-room


    【解决方案1】:

    我相信这应该对您有很大帮助: https://github.com/commonsguy/cwac-saferoom

    【讨论】:

      【解决方案2】:

      您可以对 db 文件使用 AES 加密/解密。请记住,使用的 KEY 长度为 16 位

      以下是一种可用于以加密格式导出 db 文件的方法。

      public static void exportEncryptedDB(Context context)
      {
          try {
              String appName = context.getResources().getString(R.string.app_name);
              File file = new File(Environment.getExternalStorageDirectory() + "/" + appName + "/");
              if(!file.exists())
              {
                  file.mkdirs();
              }
      
              File sd = Environment.getExternalStorageDirectory();
      
              if (sd.canWrite())
              {
                  File data = Environment.getDataDirectory();
                  String currentDBPath= "//data//" + context.getPackageName() + "//databases//" + DB_NAME;
                  String backupDBPath  = "/" + appName + "/" + DB_NAME;
                  File currentDB = new File(data, currentDBPath);
                  File backupDB = new File(sd, backupDBPath);
      
                  FileInputStream src = new FileInputStream(currentDB);
                  FileOutputStream dst = new FileOutputStream(backupDB);
      
                  // KEY Length 16 byte
                  SecretKeySpec sks = new SecretKeySpec("1234567890123456".getBytes(), "AES");
                  // Create cipher
                  Cipher cipher = Cipher.getInstance("AES");
                  cipher.init(Cipher.ENCRYPT_MODE, sks);
      
                  CipherOutputStream cos = new CipherOutputStream(dst, cipher);
                  byte[] b = new byte[8];
                  int i = src.read(b);
                  while (i != -1) {
                      cos.write(b, 0, i);
                      i = src.read(b);
                  }
                  src.close();
                  dst.close();
                  cos.flush();
                  cos.close();
      
                  Log.e("EXPORT_DB", "Database has been exported to\n" + backupDB.toString());
              }
              else
              {
                  Log.e("EXPORT_DB", "No storage permission.");
              }
          } catch (Exception e) {
              e.printStackTrace();
              Log.e("EXPORT_DB", "Error exporting database!");
          }
      }
      

      并使用这种导入方式解密db文件并存储。

      public static void importEncryptedDB(Context context) 
      {
          try {
              String appName = context.getResources().getString(R.string.app_name);
              File file = new File(Environment.getExternalStorageDirectory() + "/" + appName + "/");
              if(!file.exists())
              {
                  file.mkdirs();
              }
      
              File sd = Environment.getExternalStorageDirectory();
      
              if (sd.canWrite())
              {
                  File data = Environment.getDataDirectory();
                  String currentDBPath = "//data//" + context.getPackageName() + "//databases//" + DB_NAME;
                  String backupDBPath  = "/" + appName + "/" + DB_NAME;
                  File currentDB = new File(sd, backupDBPath);
                  File backupDB = new File(data, currentDBPath);
      
                  FileInputStream src = new FileInputStream(currentDB);
                  FileOutputStream dst = new FileOutputStream(backupDB);
      
                  // KEY Length 16 byte
                  SecretKeySpec sks = new SecretKeySpec("1234567890123456".getBytes(), "AES");
                  Cipher cipher = Cipher.getInstance("AES");
                  cipher.init(Cipher.DECRYPT_MODE, sks);
      
                  CipherInputStream cis = new CipherInputStream(src, cipher);
      
                  int b;
                  byte[] d = new byte[8];
                  while((b = cis.read(d)) != -1) {
                      dst.write(d, 0, b);
                  }
                  dst.flush();
                  src.close();
                  dst.close();
                  cis.close();
      
                  Log.e("IMPORT_DB", "Database has been imported.");
              }
              else
              {
                  Log.e("IMPORT_DB", "No storage permission.");
              }
          } catch (Exception e) {
              e.printStackTrace();
              Log.e("IMPORT_DB", "Error importing database!");
          }
      }
      

      您可以传递从用户输入中获取的KEY,并在上述方法中将其作为变量传递以进行验证。

      【讨论】:

      • importEncryptedDB 不起作用。错误日志:垫块损坏
      • @Mahan ,确保使用与加密时相同的密钥。
      猜你喜欢
      • 2020-08-13
      • 2016-09-10
      • 1970-01-01
      • 1970-01-01
      • 2021-08-13
      • 2018-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多