objectbox / objectbox-java

Android Database - first and fast, lightweight on-device vector database
https://objectbox.io
Apache License 2.0
4.38k stars 302 forks source link

Support for secure private data storage #8

Open pakoito opened 7 years ago

pakoito commented 7 years ago

Note: it is already possible to use @Convert and your encryption implementation to encrypt single properties. See an example below.


Allow configuring the proprietary serialization format to include a layer of security.

Suggestions:

greenrobot commented 7 years ago

Didn't get the "Obfuscate fields via @ annotation" part - can you give an example? Thanks.

pakoito commented 7 years ago

This is just a guess because there's no open specification of the format the data is stored on, but could the data stored possibly be read using any binary editor?

If so I'd suggest the possibility of mangling, obfuscating, or doing some kind of reversible operation before storing some fields that could be sensitive, like emails or addresses, so at least they're not plainly searchable with a tool.

greenrobot commented 7 years ago

Ah, you want to encrypt only partially, interesting idea. Not sure how indexing should handle those however. For example you could have a "greater than X" query. Here, an index is only useful if it stores plain values because the order changes once you encrypt.

pakoito commented 7 years ago

I'd solve that with documentation, if you use partial encryption it'd be understandable such fields could not used as indexes.

bigntallmike commented 6 years ago

As to encrypting individual fields: @EncryptedField String CCNumber; results in CCNumber's data being stored encrypted in the back-end and not being searchable.

Now as far as that goes, it can be implemented with getters and setters and storing the encrypted data in something like a Byte array variable instead.

adoubleu commented 6 years ago

Are there any plans for encryption support? Could you provide a schedule for the feature? We have sensible data on our product. Encryption is a MUST have feature, so we might switch to a SQLCipher compatible db if the objectbox encryption-support is far from being released.

Thank you. Best regards from Berlin,

Adrian

adoubleu commented 6 years ago

Do you have any plans to support DB encryption? Would you please provide a timeframe?

Thank you.

greenrobot commented 6 years ago

Wanted to start off some discussion about implementation: libsodium probably would be a good starting point. My last time doing encryption was a combo of ECC, AES with IV and HMAC. libsodium rather recommends ChaCha20-Poly1305 (see also RFC 7905), which is also significantly faster (in software).

Any thoughts on that?

In principle, I am thinking to encrypt only object data, not the entire DB structure (b-trees and such). This is not only much simpler to implement but also the more better performing solution. On the down side, it would allow an attacker to snoop into the b-tree structure and see plain IDs and object counts. Also indexed properties would be revealed, which could somewhat be mitigated by using hash indexes (since 2.0). My hope is that it seldom makes sense to index secure information like passwords and the likes.

Any objections/thougths/confirmations here?

Links: https://gist.github.com/atoponce/07d8d4c833873be2f68c34f9afc5a78a https://blog.cloudflare.com/do-the-chacha-better-mobile-performance-with-cryptography/ https://www.imperialviolet.org/2014/02/27/tlssymmetriccrypto.html

seyedjafariy commented 5 years ago

I have asked around a little and it seems like ECC, AES and Argon2(instead of HMAC) is the good options. I can do more searching in a few days and post if anything changes.

ps:eagerly waiting for this feature

davidhowe commented 4 years ago

So in lieu of no official database encryption support, we've gone the route of field encryption using the property converters. We've implemented AES-256 encryption on String fields. Thus far performance tests show the following: No encryption, 1000 objects (13 fields / object) write ~ 2740ms Encrypted, 1000 objects (13 fields, 6 encrypted) write ~ 6434ms No encryption, 1000 objects (13 fields / object) read ~ 58ms Encrypted, 1000 objects (13 fields, 6 encrypted) read ~ 70ms

Checkout this handy AES lib: https://github.com/scottyab/AESCrypt-Android

An example of the property converter class

class EncryptionConverter : PropertyConverter<String, String> {

    override fun convertToDatabaseValue(entityProperty: String): String {
        return AESUtil.encrypt("YOUR_SUPER_SECURE_KEY" , entityProperty)
    }

    override fun convertToEntityProperty(databaseValue: String?): String {
        return AESUtil.decrypt("YOUR_SUPER_SECURE_KEY" , databaseValue)
    }
}

Your field in entity class would look something like this

@Convert(converter = EncryptionConverter::class, dbType = String::class)
    var username : String = ""

Also remember, with field encryption you're giving up partial field lookup capability

greenrobot commented 4 years ago

@davidhowe Thanks for sharing this. Quick side question: how are you writing objects? Do you e.g. use put(objectList) passing all objects in at once?

davidhowe commented 4 years ago

@greenrobot Good question. I was running it in a loop adding one at a time. (Inefficient!) Did another test writing same 1000 entries as above comparing loop vs put(objectList) Results as follows: Encryption Loop - 7667ms put(objectList) - 789ms

No encryption Loop - 5950ms put(objectList) - 101ms

umeshNova commented 4 years ago

Can't we encrypt the db file with file encryption in jetPack? No doubt this will solve specific to android. Please refer https://blog.mindorks.com/how-to-encrypt-data-safely-on-device-and-use-the-androidkeystore.

hamzaahmedkhan commented 3 years ago

@greenrobot-team is this feature completed?

liujingtaode commented 2 years ago

Note: it is already possible to use @Convert and your encryption implementation to encrypt single properties. See an example below.

Allow configuring the proprietary serialization format to include a layer of security.

Suggestions:

  • Full document encryption
  • Obfuscate fields via @annotation

I have a table such as id message 1 VTanPBv6dWnSuDED... 2 VTanPBv6dWnSuDED... I've implemented AES-256 encryption on field ‘message‘, but I can't get an accurate result when I do a query with contains condition, eg. box.query().contains(table_.message, "search_key", StringOrder.CASE_INSENSITIVE). How to solve this problem pls?Thanks.

greenrobot-team commented 2 years ago

@liujingtaode Using the @Convert approach you can't use regular query conditions as it can only see the encrypted strings.

A workaround would be to query for all objects and use a filter which works on objects after they are returned from the database:

// Use ObjectBox Query filter
val results = box.query() // optional: add conditions to reduce result list size
    .filter { it.message.contains("search_key") }
    .build()
    .use { it.find() }

// Or use limit + offset and Kotlin filter
val results = box.query() // optional: add conditions to reduce result list size
    .build()
    .use { it.find(offset, limit) }
    .filter { it.message.contains("search_key") }

Note that using a filter comes with a performance penalty, so only use this for a small number of objects.

liujingtaode commented 2 years ago

@greenrobot-team My application is a chat app, and the requirement is to search chat records. Some user‘ message table has very large data, about 100,000 records. I have tried the method you mentioned. If I query all the data first and then filter it, the speed will be very slow, which is unacceptable to users, and the memory occupied by the app will also increase sharply. Do you have any plans to support encryption in the near future? After all, for a commercial chat app, user data encryption is an important and necessary requirement.

Looking forward to your reply, thanks.

greenrobot-team commented 2 years ago

We don't share timelines. But I can say that this feature is not being actively worked on right now.

Again, if you are interested, please thumbs up the first post. This will help us filter issues with the most interest.

robertobsc commented 1 year ago

Hey folks, just wanted to check in how are your plans for this feature. Just checked the Hive supports encryption for dbs.

For sandbox applications we don't need to have a key ourselves: we can just generate a random key and store with Apple KeyChain or Android Keystore, this is being done by FlutterSecureStorage package: https://pub.dev/packages/flutter_secure_storage

Hive: https://docs.hivedb.dev/#/advanced/encrypted_box.

Because I need encryption for my app I'm planning to use Hive, but I liked more your interface (annotations, methods) and you have more features, so I would love to use your db.