繁体   English   中英

如何检查房间数据库中的数据是否加密?

[英]How to check if data in room database is encrypted?

我正在构建一个使用房间数据库的应用程序,并使用 SQLCipher 对其进行加密。 我如何检查数据是否真的加密,因为这是我第一次使用加密,我不知道我是否正确。

假设您想检查应用程序中的数据库是否加密,那么您必须小心一点。

建议通过房间打开数据库而不使用密钥进行检查,如果数据库被加密,将导致数据丢失。

  • 这是因为当 room 试图打开加密的数据库时,它会被认为是一个损坏的数据库,因为整个文件都被加密,因此不是一个有效的数据库文件(标题字符串将不是所需的标题字符串“SQLite format 3\\ 000”)。 Room 然后将删除损坏的数据库,然后调用 onCreate 方法来提供一个没有数据的有效新数据库。

  • 请参阅当房间 android db 损坏时会发生什么?

我建议您考虑打开文件,而不是作为数据库,而是作为文件打开并检查前 16 个字节是否为“SQLite 格式 3\\000”。

如果是“SQLite 格式 3\\000”那么数据库没有被加密,如果它不是“SQLite 格式 3\\000”那么数据库(如果文件实际上是一个/数据库文件)可能被加密了。

也许考虑以下方面的事情:-

    /**
     * Check to see if the database is encrypted
     *
     * NOTE assumes encrypted if the database header string is not the required SQLite header string
     * WARNING any invalid file would be considered encrypted
     */
    fun isEncryptedDatabase(context: Context, databaseName: String): Boolean {
        var rv = false

        // SQlite header String 16 bytes as SQLite format 3\000
        //  hex representation is  53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00
        val requiredSQLiteFileHeaderString: ByteArray
            = byteArrayOf(0x53,0x51,0x4c,0x69,0x74,0x65,0x20,0x66,0x6F,0x72,0x6D,0x72,0x61,0x74,0x20,0x33,0x0)
        var dbFileHeader = ByteArray(requiredSQLiteFileHeaderString.size)
        var i: InputStream
        try {
            i = FileInputStream(context.getDatabasePath(databaseName))
            i.read(dbFileHeader)
            if(!dbFileHeader.equals(requiredSQLiteFileHeaderString)) {
                rv = true
            }
            i.close()
        } catch (e: IOException) {
            rv = true;
        }
        return rv
    }
}

您可以在 Room 之外和 Room 打开数据库之前使用它。 考虑到上面使用了 Context 的 getDatabasePath 方法,那么真正的结果(数据库被加密)很可能是由于数据库被加密而不是另一种类型的文件。

这是使用嵌入在@Database 类中的上述代码的示例(基于使用用于回答上述链接的代码)。 活动代码是:-

class MainActivity : AppCompatActivity() {
    lateinit var db: TheDatabase
    lateinit var dao: AllDao
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        if (!TheDatabase.isEncryptedDatabase(this,TheDatabase.DATABASENAME)) {
            //.... handle un-encrypted database here
        }
        db = TheDatabase.getInstance(this)
        dao = db.getAllDao()
        .... 
    }
}
  • 请注意,为了方便和简洁,上面使用了主线程(即.allowMainThreadQueries()已在 databaseBuilder 中编码)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM