androidkotlinandroid-roomtripledes

Encrypt specific column of Room database


I have a table with messages in a chat app and i want to use TripleDes encryption in the column body of the table in my Room Database. What i do now is that whenever i has an array of new messages i loop through them and change the .body field to TripleDes.encrypt(body)

// TripleDes encryption to inserted messages
   messageDtoList.forEach {
      if (it.body.isNotEmpty())
         it.body = TripleDesEncrypt.encrypt(it.body, Params.TRIPLE_DES_KEY)
     }               
   AppDatabase.invoke(MyApplication.instance).messageDao().insert(messageDtoList)

I wanted to know if there is a better and more formal way to do this


Solution

  • Using TypeConverter could be useful. I wrote a class named DecryptedString which wraps String and inner Converter class which handles encryption/decryption processes.

    class DecryptedString(var value: String = "") {
    
        class Converter {
            @TypeConverter
            fun decrypt(encrypted: String): DecryptedString {
                return DecryptedString(TripleDesEncrypt.decrypt(encrypted, Params.TRIPLE_DES_KEY))
            }
    
            @TypeConverter
            fun encrypt(decrypted: DecryptedString): String {
                return TripleDesEncrypt.encrypt(decrypted.value, Params.TRIPLE_DES_KEY)
            }
        }
    }
    

    Then instead of using String type for body field, you have to use DecryptedString type in your MessageModel class.

    
    @Entity
    data class MessageModel(
            @PrimaryKey
            var uid: Int,
    
            @TypeConverters(DecryptedString.Converter::class)
            @ColumnInfo(name = "decrypted_body")
            var body: DecryptedString
    
            //Other fields
    )