Skip to content
This repository has been archived by the owner on May 22, 2021. It is now read-only.

Password hashing / Insufficent PBKDF rounds #607

Closed
ehuggett opened this issue Oct 21, 2017 · 1 comment
Closed

Password hashing / Insufficent PBKDF rounds #607

ehuggett opened this issue Oct 21, 2017 · 1 comment

Comments

@ehuggett
Copy link
Contributor

ehuggett commented Oct 21, 2017

The newAuthKey is derived from the users password and submitted to the server, effectively a password hash. Only 100 rounds/iterations are used.

send/app/fileSender.js

Lines 239 to 261 in 9410def

const pwdKey = await window.crypto.subtle.importKey(
'raw',
encoder.encode(password),
{ name: 'PBKDF2' },
false,
['deriveKey']
);
const newAuthKey = await window.crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: encoder.encode(file.url),
iterations: 100,
hash: 'SHA-256'
},
pwdKey,
{
name: 'HMAC',
hash: 'SHA-256'
},
true,
['sign']
);
const rawAuth = await window.crypto.subtle.exportKey('raw', newAuthKey);

xhr.send(JSON.stringify({ auth: arrayToB64(new Uint8Array(rawAuth)) }));

Stackoverflow user "Tails" has compiled a list how many rounds are recommended/actually used in some implementations

  • Sept 2000 - 1000+ rounds recommended (source: RFC 2898)
  • Feb 2005 - AES in Kerberos 5 'defaults' to 4096 rounds of SHA-1. (source: RFC 3962)
  • Sept 2010 - ElcomSoft claims iOS 3.x uses 2,000 iterations, iOS 4.x uses 10,000 iterations, shows BlackBerry uses 1 (exact hash algorithm is not stated) (source: ElcomSoft)
  • May 2011 - LastPass uses 100,000 iterations of SHA-256 (source: LastPass)
  • Jun 2015 - StableBit uses 200,000 iterations of SHA-512 (source: StableBit CloudDrive Nuts & Bolts)
  • Aug 2015 - CloudBerry uses 1,000 iterations of SHA-1 (source: CloudBerry Lab Security Consideration (pdf))

The AuthKey is used to sign a nonce. Some suggestions

  • Increase the number of PBKDF2 rounds until the performance impact would be noticed by the user
  • The WebCrypto API supports asymmetric keys, RSASSA-PKCS1-v1_5 and ECDSA, the use of which would only require the public key to be submitted to the server
  • HKDF should allow a salt to be set, I'm thinking the password could be used here? (regenerate the authKey using the password as a salt, so that newAuthKey is derived from both secretKey AND password). The advantage of this is it would require knowledge of the secretKey to attempt brute force password discovery (should anyone obtain the newAuthKey from the Send server)

edit: Accidentally submitted this issue before i had finished writing it

@ehuggett
Copy link
Contributor Author

I missed something important

salt: encoder.encode(file.url),

file.url is the complete download link, including the base64 encoded secretKey. Therefore the newAuthKey is already derived from a secretKey AND password and should be quite safe from brute force.

100 rounds is more than sufficient, as the encoded secretKey is adding 128 bits of entropy to the users password

Sorry, Closing!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant