realm / realm-java

Realm is a mobile database: a replacement for SQLite & ORMs
http://realm.io
Apache License 2.0
11.45k stars 1.75k forks source link

Increase encryption key size to at least 2048 bit #3309

Closed carlbenson closed 8 years ago

carlbenson commented 8 years ago

Goal

Realm supports 512 bit key size for encryption which is too low for financial applications and personal data.

Expected Results

Realm should increase supported key size to at least 2048 bit for increased security.

cmelchior commented 8 years ago

Realm is using AES, not RSA. You cannot compare key sizes across different crypto algorithms, especially since AES is symmetric while RSA is asymmetric.

AES-256 is considered just as secure as RSA-2048: http://security.stackexchange.com/questions/8086/aes-256-or-rsa-2048-for-web-application-security

https://en.wikipedia.org/wiki/Advanced_Encryption_Standard

carlbenson commented 8 years ago

Great, thanks! :)

jagan999 commented 7 years ago

I'm not able to pass in a 64 byte key to Realm Encryption since even AES does not accept any key size less than 128. Any suggestions? This is preventing me from using Realm since I need only an encrypted version of Realm for my app

cmelchior commented 7 years ago

@jagan999 We use AES-256 which takes a 256 bit key, not bytes ... Since a byte is 8 bit, we thus take a 512 (64x8) bit key. The first 256 bits used used by AES, the last 256 bits by the HMAC.

jagan999 commented 7 years ago

Thanks. I've been spending the last two days but still not able to store and reuse the same key for Realm encryption. I have tried to store a secret key in my alias which it does successfully and retrieves the next time I open the app. However, I am not able to reliably and consistently get the same byte array from the secret key to supply to Realm Encryption. Even though it finds the SecretKey from Android KeyStore, when I load this in a cipher and do cipher.doFinal, it gives me different byte array everytime. Is there a way you can help? I have searched all over Google to no avail. Issue is that Android does not export public material, hence I cannot use SecretKey.getEncoded - this is always null

cmelchior commented 7 years ago

You need to do a double key layered approach. Create a random key you store in the AndroidKeyStore, then create the key used by Realm. You can then use the Keystore to encrypt/decrypt the Realm key and just store the encrypted Realm key in SharedPreferences or in a file somewhere.

You can use this as a starting point: https://github.com/realm/realm-android-user-store/tree/master/app/src/main/java/io/realm/android

jagan999 commented 7 years ago

Thanks a ton...! Your great explanation and pointer to the source code helped me get encrypted Realm up and running. You really saved me a lot of trouble, Thanks again

jagan999 commented 7 years ago

Spoke too early...i actually had a bug in the code that seemed like it was working. Well, now I have encryption and decryption exactly like you've suggested. I encrypt the username with my secret key/AES cipher and then encrypt this AES key using my RSA public key from my privatekey entry. Decryption exactly works in reverse and I am able to get my decrypted username consistently. Now, issue I'm having is in gettinga 64 byte key for Realm encryption. The AESKey is only 16 bytes and the RSAEncryptedAESKey is 256 bytes...neither works for Realm.

jagan999 commented 7 years ago

I've been struggling with this 64 byte thing for all day today. I understand that ciphers initialized with AES will only encrypt to 16 bytes whatever be the case. When I pass this encrypted data to a message digest with SHA-256, the message digest gives me 32 bytes. Now, I have only 48 bytes in all but I need 64 bytes for Realm encryption. Is it ok to pad zeroes until I reach 64 bytes? Realm encryption has become very frustrating. I've spent 3 full days and still not cracked this.

pkhivesara commented 5 years ago

@carlbenson Does Realm support being able to use an encryption key which is larger than 512 bit? And can we also change the encryption type used on the database itself to something other than the standard AES-256.

cmelchior commented 5 years ago

@pkhivesara No, you cannot change the size of the keys involved nor which encryption algorithm is used. I'm not sure why you would want to do that though, AES-256 should be safe for all practical purposes.

Edit: You can also see https://crypto.stackexchange.com/questions/20253/why-we-cant-implement-aes-512-key-size

pkhivesara commented 5 years ago

Sorry for being such a noob @cmelchior . But in your opinion, would the standard AES-256 encryption on database suffice for a financial/health information app? Or can i run a SHA-256 on the generated 512 bit key and then pass that in for added security?

cmelchior commented 5 years ago

Yes, AES-256 is considered safe for finacial/healthcare data: https://crypto.stackexchange.com/questions/2251/how-secure-is-aes-256