makersphereHQ / emojico

Use emojis instead of weak passwords. 🍫🍿🍩πŸ”₯😎
https://makersphere.org/emojico
GNU General Public License v3.0
9 stars 2 forks source link

Use jsSHA with Increased Number of Rounds #5

Open daknob opened 8 years ago

daknob commented 8 years ago

When hashing something, for example a password, it is a good practice to hash it more than one time so as to increase the work an attacker has to do assuming they receive the hash. In this program, while you may not be storing these passwords and risking them being leaked, you provide a service similar to the Bitcoin Brainwallet. The most popular solution of this software used a single iteration of SHA-2 to create the wallet's private key. This lead to many people brute forcing all passwords up to a few characters and storing their private keys beforehand, allowing them to steal all the BTC from people using weak passwords.

A good solution to slow attackers down / prevent them from getting up to large lengths of passwords is to use multiple iterations of the hashing algorithm. For example, if instead of a single SHA-512 that's being used currently, you did 1,000 or 5,000 or 10,000 iterations, it would increase the cost of the attacker 1,000 or 5,000 or 10,000 times respectively. Now keep in mind this also slows down by the same factor all the legitimate users, so you may want to play with this until you arrive at the correct value. The general recommendation is "As much as you can afford".

jsSHA already has a numRounds parameter that you can pass to achieve this, however its internal workings are unknown to me, therefore I cannot guarantee its efficiency / security. However, it is a good start that can help you enhance your product's security very quickly.

makersphereLabs commented 8 years ago

Sounds like we need to do some UX testing before we can push a new version. Just an idea, but in theory we could calculate how many iterations are "affordable" for each user using JS. Cool?

daknob commented 8 years ago

Unfortunately I don't think you can measure for example how many iterations the client can make in a second, which the common practice for iterative hashing. The reason is because other forms of hashing store the iteration count somewhere, while your application is not persistent anywhere: no cookies, no Local Storage, etc. Having this option in the UX is maybe too much because it reduces simplicity.

If you opt-in for the benchmark method, it may be able to do 12,341 iterations on Monday and 9,884 on Tuesday. It won't be constant. Even if you round up to the nearest thousand, it's still not effective.

From an engineering point of view, it looks like the easier and best solution is a hardcoded number.

makersphereLabs commented 8 years ago

Good point. Makes sense, because if we measure let's say on Monday 12,341 iterations and the next day (you have a bunch of tabs open, youtube playing, etc.) just ten iterations less, everything would be worthless! Just imagine the poor people sitting in front of their computers, looking super sad because they are locked out of their password managers. And we don't want that, right? πŸ˜…

atoponce commented 8 years ago

Created pull request #8 to move the password hashing function from SHA-256(SHA-512(password)) to a dedicated password hashing function of scrypt(password). Currently, it uses a static salt, which is not great. The salt should be random and unpredictable, but where this application is basically just encoding UTF-8 emoji characters into a base64 string, it's fine. If you provided a random salt, then when entering the same emoji sequence, you would always get a different base64 string.

Regardless, generic cryptographic hashing functions should not be used for password hashing. Use dedicated password-base key derivation functions or dedicated password hashing functions for this purpose.

makersphereLabs commented 8 years ago

@atoponce Agree with you on the hashing issue. πŸ€” Our assumption is that you're using a service that stores passwords in plaintext (don't do that), that would be the worst case scenario, which is unfortunately not unrealistic... πŸ™„ So the hashing function needs to be strong enough, to provide decent security, even if your credentials are leaked. Anyway, thanks for the PR! πŸ™Œ

atoponce commented 8 years ago

@makersphereLabs No problem. The reason scrypt should be used over generic cryptographic hashing functions, is because you don't want a password cracker to quickly guess the base64 password by working through emoji quickly, creating large rainbow tables.

Unfortunately, people will use common emoji sequences for their password generation, such as creating sentences or stories with their emoji. By using a fast cryptographic hashing function, password crackers can build rainbow tables of common sequences quickly. By using a slow dedicated password hashing function, it becomes expensive to create those tables.

By increasing the emoji length to 7 from 4, it now requires 1791^7 work with a slow function to create the rainbow table instead of 1791^4. The amount of work has increased exponentially.

makersphereLabs commented 8 years ago

@atoponce Yep, rainbow tables could become an issue. But we can help the user to use a "good story" instead of e.g. 🍩🍩🍩🍩, when we prohibit the use of super common stories. Like 4x the same emoji.