Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decrease number of kdf iterations in pfs database #1343

Merged
merged 1 commit into from
Jan 11, 2019

Conversation

rasom
Copy link
Member

@rasom rasom commented Jan 8, 2019

PFS database key is derived via pbkdf which runs 64000 iterations of sha1. This makes Login call quite slow on android devices (probably on iOS too, but it didn't work on iOS).

This PR changes the number of iterations to 3200, and, well, makes it faster. The problem is that from security pov key becomes kind of weaker( currently, that's probably not the case as the same key is used for keystore file and it can be encrypted way faster, so no point in brut-forcing pfs database key at all).

Migration is done using sqlcipher_export command.

@status-github-bot
Copy link

status-github-bot bot commented Jan 8, 2019

Pull Request Checklist

  • Have you updated the documentation, if impacted (e.g. docs.status.im)?

@rasom rasom force-pushed the pfs_db/change_kdf_iter branch 4 times, most recently from e2f9460 to 7ac63cd Compare January 9, 2019 16:14
@rasom
Copy link
Member Author

rasom commented Jan 9, 2019

On the other hand, we also have realm db on the client side, and this one is encrypted via sha256(random_key + password), where random_key is some random bytes generated for each account and stored in devices keychain/keystore. In case if an attacker has access to db files but doesn't have access to keychain/keystore brut-forcing is kind of useless.

So the question is what should be done here

a. let's decrease the number of iterations to 3200, that's fine for now (still doesn't make too much sense IMO because of account's keystore, the attacker isn't going to brute-force this db now anyway)
b. use the same key as for realm db, or the key which is derived in a similar way, thus skip pbkdf
c. use some completely different scheme for key derivation, but again skipping pbkdf

@rasom rasom changed the title [WIP] lower number of kdf iteration in pfs database [WIP] lower number of kdf iterations in pfs database Jan 9, 2019
@mandrigin
Copy link
Contributor

@rasom @cammellos are the messages from PFS-protected chats also stored in the realm DB?

@rasom
Copy link
Member Author

rasom commented Jan 9, 2019

@mandrigin yep i think so, not 100% sure though

@mandrigin
Copy link
Contributor

If the messages plaintexts are stored in Realm anyway, is there a point to protect the SQLite DB better?

@cammellos
Copy link
Member

cammellos commented Jan 9, 2019

They are, unless the user removes them.

Personally I don't find the argument "other part of the app have lower security" convincing, as argument to reduce current security of the app. if anything we should improve security in the rest of the app, not lowering it.

Performance of slower devices is a fair trade-off so lowering the value it's a choice, removing it completely does not make much sense.

To go into the specifics, there are quite a few cases where having a stronger encryption on this db might just be what prevents a successful attack, even if the rest is compromised.

Mind that this keys are used for data transferred on the wire, locally you always have the option to delete the deciphered text (messages), while ciphertext transferred on the wire anyone can intercept and keep indefinitely.

Say you deleted compromising messages on your phone, and someone has physical access to your phone. If they can break in to realm database, they won't be able to retrieve the compromising messages. But if they have been collecting previous messages (trivial) and they bruteforce the sqlcipher db then they have access to the compromising texts.

Anyone using status-go as well without using status-react would also be affected.

It's not clear to me what the argument to remove is, are we still not happy with the performance on slower devices?

@cammellos
Copy link
Member

Basically the assumption that anything confidential is stored in realm, is just not true currently (messages can be deleted), and likely won't hold in the future (confidential info might be sent but not stored).

@cammellos
Copy link
Member

@corpetty probably you might want to join the conversation

@rasom
Copy link
Member Author

rasom commented Jan 9, 2019

It's not clear to me what the argument to remove is, are we still not happy with the performance on slower devices?

arguments to remove:

  1. it is slow. Not only on slower devices, but it is also noticeably slow on faster Android devices (on galaxy s9 Login call takes 2.2-2.3s and most of that time is key derivation) and we just figured that it hasn't been applied on iOS at all. So it might be slow there as well.
  2. if it's not slow it is kind of useless, that's the whole point of pbkdf2. Here it's 3200 iterations when in the latest version of sqlcipher that kdf_iter is 256000 (80x) by default. It is recommended as i understand. So if we use the recommended value on, let's say, galaxy s9 it's not going to be 2 seconds anymore, but 7-8 seconds to derive the key from a passphrase.
  3. If we can bring randomness into key derivation we can defend against brute-force attacks in a different manner. And the cost of key derivation will be much lower. So well, if we can do this (and do this properly), why not?

Anyone using status-go as well without using status-react would also be affected.

easy to solve in API, we can explicitly tell users when the key will be derived or when a raw key will be used. No problem to use pbkdf on a desktop, for instance.

@cammellos
Copy link
Member

Fair enough, my understanding was that only slow devices were affected.

If we can bring randomness into key derivation we can defend against brute-force attacks in a different manner. And the cost of key derivation will be much lower. So well, if we can do this (and do this properly), why not?

That sounds reasonable, but then let's just do that and we can remove it, I'd say

@rasom
Copy link
Member Author

rasom commented Jan 10, 2019

Statusgo.Login duration

galaxy S9
64000 2.1s (~1.694s for pbkdf)
6400 0.575s (~0.169s)
3200 0.5055s (~0.09s)
256000 kdf iterations will cost approximately 6.7s (assuming the same algorithm is used), then Statusgo.Login will take ~7.1s

samsung a500h
64000 8.72s (~7.37s for pbkdf)
6400 2.08s (~0.74s)
3200 1.75s (~0.4s)
256000 kdf iterations will cost approximately 29.5s (assuming the same algorithm is used)then Statusgo.Login will take ~31.8s

Copy link
Contributor

@corpetty corpetty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this doesn't directly affect the user's password or key derivation outside of this DB, and this is only hardening the DB from other content unlocked by user's password. I am ok with this. Furthermore, the password being iterated is not the user's password, but it's hash.

I am not ok with the removal of the iterations.

@rasom
Copy link
Member Author

rasom commented Jan 11, 2019

@rasom rasom changed the title [WIP] lower number of kdf iterations in pfs database [WIP] decrease number of kdf iterations in pfs database Jan 11, 2019
@rasom rasom changed the title [WIP] decrease number of kdf iterations in pfs database Decrease number of kdf iterations in pfs database Jan 11, 2019
`kdf_iter` parameter is reduced to 3200. This change is done because of
performance reasons, currently key derivation is too slow on some mobile
devices. The number of iterations before this commit is 64000, default
value in `sqlcipher` from version `3.0.0`.
https://github.com/sqlcipher/sqlcipher/blob/fda4c68bb474da7e955be07a2b807bda1bb19bd2/CHANGELOG.md#300---2013-11-05

Implementation:
`sqlcipher_export` is used for migration, check out the link below
for details
https://www.zetetic.net/sqlcipher/sqlcipher-api/#sqlcipher_export
@cammellos cammellos merged commit d6216f1 into develop Jan 11, 2019
@rasom rasom deleted the pfs_db/change_kdf_iter branch January 11, 2019 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants