LinusU / secure-remote-password

A modern SRP implementation for Node.js and Web Browsers
102 stars 22 forks source link

PBKDF2 Example ? #1

Open alexgoldstone opened 6 years ago

alexgoldstone commented 6 years ago

Do you have an example using PBKDF2 that you can share for reference since that is your recommended implementation?

LinusU commented 6 years ago

Absolutely! I'll try and post this in the next few days, feel free to nag me if I forget 😄

alexgoldstone commented 6 years ago

Hi Linus. I've resurrected my project and was re-reading your README which suggests using PBKDF2.

Just therefore wanted to drop you a friendly reminder that you were going to share an example implementation for this.

Thanks.

LinusU commented 6 years ago

You can see how I'm using it here:

https://github.com/ctrl-alt-deseat/ctrlpanel-core/blob/0feaff054a2e9d3f7d63595c911f6f0963ba0486/src/core.ts#L303-L316

and here:

https://github.com/ctrl-alt-deseat/ctrlpanel-core/blob/c8cff059231cf1fa8a1d11ae745970c2278e2114/src/crypto.ts#L40-L55

Basically it boils down to something like:

const pbkdf2 = require('@ctrlpanel/pbkdf2')
const encodeUtf8 = require('encode-utf8')

const PBKDF2_HASH = 'SHA-512'
const PBKDF2_ITERATIONS = 500000
const PBKDF2_KEYLEN = 32

// ...

async function (username, password) {
  // get `salt` from server
  const salt = '...'

  // generate hash
  const privateKey = arrayBufferToHex(await pbkdf2(encodeUtf8(`${username}:${password}`), salt, PBKDF2_ITERATIONS, PBKDF2_KEYLEN, PBKDF2_HASH))

  // use hash with SRP
  const verifier = srp.deriveVerifier(privateKey)
}

I would love for this to be improved and added to the readme!

dobesv commented 5 years ago

I made a PR to add this to the README:

https://github.com/LinusU/secure-remote-password/pull/20

abhijithvijayan commented 5 years ago

@dobesv @LinusU I used another pbkdf2 hashing using fash-sha256, and I have the output as a Uint8Array.

What am I supposed to convert this into?

an arrayBuffer then to Hex?

coz on trying to login, I am seeing

RangeError: Expected string to be an even number of characters
    at hexToArrayBuffer (index.js:7)
    at sha256.js:25
    at Array.map (<anonymous>)
    at sha256 (sha256.js:23)
    at Object.push.../../node_modules/secure-remote-password/client.js.exports.deriveSession (client.js:96)
    at deriveClientSession (deriveClientSession.js:5)
    at _callee6$ (actions.js:264)
    at tryCatch (runtime.js:62)
    at Generator.invoke [as _invoke] (runtime.js:288)
    at Generator.prototype.<computed> [as next] (runtime.js:114)
    at asyncGeneratorStep (asyncToGenerator.js:5)
    at _next (asyncToGenerator.js:27)
abhijithvijayan commented 5 years ago

also I have to use the same pbkdf2 while deriving the privateKey in step 3 right?

dobesv commented 5 years ago

Yeah any time you are making a private key from a password input and salt, use the same algorithm.

abhijithvijayan commented 5 years ago

@dobesv The key should be in hex format to the verifier derive and client session derive functions right?

dobesv commented 5 years ago

You can try converting it to hex. Experiment, look at the source code, you can figure it out.

abhijithvijayan commented 5 years ago

I converted it to a hex.

after using the pbkdf2 derivation, sometimes, the user is successfully logged in, sometimes it throws this error

RangeError: Expected string to be an even number of characters
    at hexToArrayBuffer (index.js:7)
    at sha256.js:25
    at Array.map (<anonymous>)
    at sha256 (sha256.js:23)
    at Object.push.../../node_modules/secure-remote-password/client.js.exports.deriveSession (client.js:96)
    at deriveClientSession (deriveClientSession.js:5)
    at _callee6$ (actions.js:264)
    at tryCatch (runtime.js:62)
    at Generator.invoke [as _invoke] (runtime.js:288)
    at Generator.prototype.<computed> [as next] (runtime.js:114)
    at asyncGeneratorStep (asyncToGenerator.js:5)
    at _next (asyncToGenerator.js:27)

Edit: I found this was due to the bogus value sent when user was not found or the verifier/salt was not found in DB