Hashing "MYpassword
" using SCrypt in Spring twice generate two different hashes which is the expected result since the salt is different.
hash 1: $100801$DBrs3RHYQafAjmY0RGGgtA==$VB1ahwEHntb36HWbAF1Eiy6FoJp1WH8xmpYY4+oHPUk=
hash 2: $100801$0EEqkaQUDzVCttua+jqu9A==$tstqjgsW5bzWXwRZKIeVy9P3jh/92QrZ8SW+8iLl7dc=
What I don't understand is that to verify the password, Scrypt needs the original salt used to hash. After searching, I found out it gets the salt from the hash field itself. So where is it exactly in the above examples? I searched for scrypt format decoded and nothing came up.
Per the source code,
private String digest(CharSequence rawPassword, byte[] salt) {
byte[] derived = SCrypt.generate(Utf8.encode(rawPassword), salt, this.cpuCost, this.memoryCost,
this.parallelization, this.keyLength);
String params = Long.toString(
((int) (Math.log(this.cpuCost) / Math.log(2)) << 16L) | this.memoryCost << 8 | this.parallelization,
16);
StringBuilder sb = new StringBuilder((salt.length + derived.length) * 2);
sb.append("$").append(params).append('$');
sb.append(encodePart(salt)).append('$');
sb.append(encodePart(derived));
return sb.toString();
}
The parameter, salt, and hash are appended next to each other with $
separator, so the middle value is the encoded salt.