Password hasher using PBKDF2-SHA256 via Web Crypto.
hash(secret: string): Promise<string>
Hash a secret (password) with a random salt.
verify(stored: string,secret: string): Promise<boolean>
Verify a secret against a stored hash.
A wrong secret returns false; a stored value that is not a well-formed
pbkdf2$… string throws MalformedPasswordHashError, because
that shape of failure is a programming error (most often reversed
arguments) rather than a failed login.