Crypto Analysis and Recommendations for Mega
spideroak.com
spideroak.com
That's because Mega is designed as simply an API that any client (including one distributed as a desktop application) could implement. However, another client implementing this same spec would have the same weaknesses. It's important that we get the design improved now. Then we can go on to build open source clients outside of the perils of the JS runtime.
Edited to add: If anyone is interested in building such a open source desktop client in Python, I could help by making our (SpiderOak's) toolchains, packagers, and installers available.
Edited again to add: Assuming a solid design and implementation is eventually produced in Javascript, you could probably re-use most of the code and avoid the JS runtime dangers by repackaging it as a desktop app with something like http://appjs.org/ Remember that of course your privacy is based not just on you using a secure client, but everyone you share data with doing likewise.
One question I have is why SpiderOak client is not open-source? As I understand, it is Python and decompiling it for analysis is not too much trouble, but still...
I should also note that the crypto code in SpiderOak is in one specific module, and we have repeatedly paid for careful audits of that code.
Lastly, we have a new crypto product in the works which we will announce at RSA in February, which is 100% open source, and of particular interest to developers in addition to SpiderOak customers. Please stay tuned!
Is there a form somewhere to leave my email?
Thanks!
Or RSS, Twitter, FB, or create a free account for email updates.
Now it gets all of them for free and likely it would use them to harden the service.
It would have been better for their users, however, if they'd tried to get this right before releasing. Mega smells very much like marketing over technology.
Where would you get this salt from on the client side? That salt has to be the same every time a user tries to access their data from a different computer, otherwise you wouldn't be able to decrypt your files with the derived key right? So how is this salt magically transferred from one computer to another? The alternative is that you get the salt from the server along with the encrypted file, but then I don't see how that improves security. Or perhaps what I'm saying here is pure nonsense, in that case I'd very much appreciate a clarification.
Both salts are created by the client from random data at the time the account is created, and saved to the server. So when a user wants to authenticate, you can just give them the plaintext of the challenge salt along with the issued challenge. There's no harm since it's just random data and shouldn't help them to calculate an answer to the challenge if they don't know the pass phrase. (Note that you only give them the challenge salt, not both salts.)
If you want the server to avoid disclosing the existence/non-existence of an account with a particular name (wise!) then just give them a made up random string as a challenge for non-existent accounts. Cache it somewhere so you can be consistent. Always rate limit login attempts.
Hope that makes more sense. :)
By including a random per-user salt, even assuming the attacker has access to the salt, the output of the KDF now varies on both a per-user and per-password basis.
Two users with the same password have different keys under this design, so pre-computing something that works for all users becomes infeasible.
If the KDF is weak in other ways, e.g., it is so fast that one doesn't need to pre-compute anything, that's a separate issue.
1. You have a whole bunch of encrypted files from different users. 2. The KDF is slow compared to checking if decryption with a given output of the KDF is successful.
With a salt this will take time nm(T + Q) where n is the number of files, m is the number of different passwords and T is the time it takes to execute the KDF and Q is the time it takes to try to decrypt with a derived key. Without a salt you can amortize the KDF executions for a total time of mT + nmQ.
In particular it doesn't help you decrypt one specific file, and the total time is still on the order of n*m, so unless Q is very cheap compared to T this won't help much (obviously still a good idea to do the salting though).
In this context, a KDF is used for verifying that a message is valid. I have a derived key, you give me a key, and I verify that key by running it through the KDF. If KDF(your_key) == derived_key then we have "proven" that your_key is valid.
Another way of thinking about it is that the image of a KDF should map low-entropy input to high-entropy output. Depending on what we're using the KDF for, we might also want it to have other properties, e.g., intentionally slow, intentionally memory intensive, etc.
This is different than you encrypting something, sending me the encrypted message, and me decrypting it using a shared secret.
http://en.wikipedia.org/wiki/Key_derivation_function http://en.wikipedia.org/wiki/Rainbow_table
In a salted system, your hash("hello" + salt1) != my hash("hello" + salt2), and I have no way of guessing your password since the hashes are different.
What we're trying to protect against is someone in possession of the data (such as Mega themselves, or anyone working for them, or hacking them, or seizing their assets, or just someone over the internet making an offline attempt against an account after discovering the auth hash) from making a brute force attempt to learn the plaintext content of the accounts.
So to help me crack accounts, I could make a database of outputs from the KDF, with every password combination pre-computed. "Start with "aaaaaa" as a password, and go all the way through "ZZZZZZ" out to some number of characters. The database would have 32 output bytes per entry. The first 32 bytes would be the output of "aaaaaa" through the kdf, then "aaaaab", and so on.
If my math is right, going out to 6 characters using letters numbers and punctuation, the database (probably just a file really) would be about 5 TB in length, and based on my single slow CPU's AES speed, would take about 99 CPU days to compute. Of course if you have 100 CPUs (or EC2, or a botnet) you could have it done in time for dinner tomorrow. Or just wait because someone will likely precompute one you can bittorrent in the next few days.
So, if I wanted to make a brute force attack against Mega's database of users, I would use this pre-computed database, reading it sequentially from disk, taking every 32 byte section and trying it as a key to decrypt the next layer of keys for a user. My CPU could likely check answers faster than the data would stream in from the disk.
So I would be able to brute force any combination out to 6 password characters in a few minutes using only the spare hardware sitting around my office and unoptimized code. Imagine what NSA could do.
So, finally getting back to answering your question. If the salt were used, then I couldn't pre-compute the KDF output. I would have to do it separately for each user. So then my attempts would (again on my weak CPU) proceed at only about 520 attempts per second. That's still about 500 times to fast. So, the design needs both a slower KDF, and salt. :)
Trivia: Want to time your own CPU and how many AES cycles it can do?
$ openssl speed -evp aes-128-ecb
Doing aes-128-ecb for 3s on 16 size blocks: 102358287 aes-128-ecb's in 3.00s
>>> 102358287 / 3 / 2**16
520
Hopefully that makes sense!Let's say everyone did as you propose and use usernames for salts. I could pre-compute dictionaries for usernames like root, admin, etc. and likely gain full access to a wide range of systems.
Our aim is to build a system where brute-forcing is always the cheapest option. Once that's the case, we're in a position to control "how expensive" it is for someone to invert even one derived key.
I am not sufficiently familiar with KDFs but I know that rainbow tables exist to crack straight up md5 hashed passwords for common usernames and passwords where the username has been used as the salt.
Maybe harder to do with a KDF because it's prohibitive to compute that many keys in the first place?
Imagine if UNIX systems did as you propose. The rainbow table for the salt "root" would let me do plenty of damage.
Well, the w3c is creating a recommendation for js crypto APIs, so maybe we'll soon see more services like this.
I wish Dropbox and SpiderOak would mate and have a child product that was as smooth, fast and easy to use as Dropbox, but with full SpiderOak grade client side encryption.
But he might not be like me, so I dunno.