keybase / keybase-issues

A single repo for managing publicly recognized issues with the keybase client, installer, and website.
900 stars 37 forks source link

Further Explanation on Login Hashing #406

Closed IsaiahJTurner closed 10 years ago

IsaiahJTurner commented 10 years ago

I'm trying to understand how the login works specifically, pwh = scrypt(passphrase, hex2bin(salt), N=215, r=8, p=1, dkLen=224)[192:224]

The other part, hmac_pwh = HMAC-SHA512(pwh, base64decode(login_session)) seems to be fairly straight forward but could someone point me in the direction of how the first part works? Also, why was does scrypt need to be used? What is wrong with just using SHA512 hashes?

lgarron commented 10 years ago

scrypt prevents someone from trying to find out what your password is without doing a lot of work each time they want to check any password for any user (even if two users have the same password). scrypt is meant to improve on the better-known bcrypt, although for a long time it was not considered quite as battle-tested (it's arguably catching up, due to the use in alternative cryptocoins). See this famous post.

HMAC seems to be used here to to derive a key based on the session. Where exactly is this code?

IsaiahJTurner commented 10 years ago

@lgarron It is a part of the login API (apparently).

"scrypt prevents someone from trying to find out what your password is without doing a lot of work each time they want to check any password for any user (even if two users have the same password)." Isn't that EXACTLY what a unique salt to a password hash does?

lgarron commented 10 years ago

Yep. scrypt includes a salt, just like bcrypt. The main feature compared to a plain salted hash is that it's a standardized construction that forces the hash to take much longer.

malgorithms commented 10 years ago

@IsaiahJTurner - the goal of a unique salt is to make it so you can't test multiple users' passwords at the same time. For example, if I steal a database of password hashes, and I hash a common password as a test, I can check across all users if there are any matches. Unique salting prevents this attack.

scrypt in comparison to a conventional hashing function is very expensive to perform -- it takes a lot of RAM and CPU time to calculate. This is to make a brute force attack expensive.

Consider our side project warp wallet: https://keybase.io/warp which is a bitcoin "brain wallet" where it does a lot of scrypt rounds to generate a bitcoin wallet. (It might crash a mobile browser.)

As @lgarron says, bcrypt has a lot of historical popularity, but scrypt is gaining popularity because (1) it targets memory usage which makes it hard to implement custom ASIC hardward to attack, and (2) it's used in litecoin.

IsaiahJTurner commented 10 years ago

@malgorithms Where is the javascript implementation for scrypt that Keybase uses for login?

malgorithms commented 10 years ago

Max's implemention of scrypt is inside our TripleSec library, and it hasn't been abstracted out as its own module. But you can use it from there if you like:

# coffeescript, but I'm sure you can figure out the JS
ts = require 'triplesec'

args = 
  key:           ts.WordArray.from_utf8('hi there'),
  salt:          ts.WordArray.from_utf8('salt'),
  progress_hook: (p) -> console.log JSON.stringify(p)
  dkLen:         224
  N:             15
  r:             8
  p:             1

ts.scrypt args, (word_array) ->
  console.log word_array.to_buffer()[192...224].toString('hex')

Here's the link to the github module:

https://github.com/keybase/triplesec

But there are lots of implementations of scrypt. No reason to use ours...we do like it because it has nice progress hooks, defers regularly so the CPU isn't blocked, etc.

IsaiahJTurner commented 10 years ago

Thanks! Keybase for iOS is coming along nicely.

maxtaco commented 10 years ago

Cool. There's also a ruby implementation at keybase/ruby-core, and someone was hacking on a python version too.

maxtaco commented 10 years ago

(But these versions are incomplete as of yet)