I'm working on a migrating an older ruby-on-rails site to node/express/react/redux, and I've run smack into a wall on authenticating users' existing passwords. The site is currently using AuthLogic(scrypt) for authentication/password hashing, with some older account passwords still hashed with the sha512 AuthLogic algorithm.
I can't for the life of me figure out how to replicate authLogic's scrypt algorithm in Node. I've reviewed the ruby source incantations for AuthLogic and the underlying scrypt package, which gave me some clues.
I'm using the latest version of the npm scrypt package (I've tried a few others without discernable differences).
The stored hash looks like this:
400$8$1d$3fbb0d3688d9da6d$5dd919ace6bdf946d48946e9dd61f0afc5116986433633e24e58809c12b5ce9a
The database also stores a unique salt parameter: fbMQa7EhFp5tdOhNsT
Based on the scrypt gem source, it looks like the $ delimited segments are the cost factor and salt:
n, r, p = args[0].split('$').map{ |x| x.to_i(16) }
from Scrypt gem scrypt.rb source.
Based on the code, it looks like first three $ delimited bits are "cost" factor for scrypt and last one is the salt. I have no idea why this salt differs from the salt stored in database, or how I should be plugging them in. This led me to try:
const n = parseInt("400", 16)
const r = parseInt("8", 16);
const p = parseInt("1d", 16)
const result = scrypt.hashSync("[my password]",{"N":n,"r":r,"p":p}, 32, 3fbb0d3688d9da6d);
The result of that is a different hash than the database store, but at least the right length.
80e302f9f8942ec9d81fe217c03730b5b8256b22cd91ad2dd2a448ec588ec390
So I tried a comparison:
const comparision = scrypt.verifyKdfSync(
"5dd919ace6bdf946d48946e9dd61f0afc5116986433633e24e58809c12b5ce9a",
"[mypassword]");
But this fails, telling me that data is not scrypt-hashed data. I tried adding various bits of the cost factor and salt, with and without $ delimiters to the hash, to no avail. I tried turning the hash into a buffer object, also to no avail. Trying kdfSync with above options also failed (error computing derived key). Online tools also don't recognize the stored hash as an scrypt hash.
Help me Ruby magicians (or anyone else with cyrptographic chops), you're my only hope(s).