57 lines
1.9 KiB
Crystal
57 lines
1.9 KiB
Crystal
require "./abstract"
|
|
|
|
module Sodium::Password
|
|
# Argon2 password hashing. A modern substitute for scrypt, bcrypt or crypt.
|
|
#
|
|
# Often used to store password hashes on a server and authenticate clients against the stored hash.
|
|
#
|
|
# Usage:
|
|
# ```
|
|
# pwhash = Sodium::Password::Hash.new
|
|
#
|
|
# pwhash.mem = Sodium::Password::MEMLIMIT_MIN
|
|
# pwhash.ops = Sodium::Password::OPSLIMIT_MIN
|
|
#
|
|
# pass = "1234"
|
|
# hash = pwhash.create pass
|
|
# pwhash.verify hash, pass
|
|
# ```
|
|
#
|
|
# Use `examples/pwhash_selector.cr` to help choose ops/mem limits.
|
|
class Hash < Abstract
|
|
# Apply the most recent password hashing algorithm against a password.
|
|
# Returns a opaque String which includes:
|
|
# * the result of a memory-hard, CPU-intensive hash function applied to the password
|
|
# * the automatically generated salt used for the previous computation
|
|
# * the other parameters required to verify the password, including the algorithm identifier, its version, ops and mem.
|
|
def create(pass)
|
|
outstr = Bytes.new STR_SIZE
|
|
if LibSodium.crypto_pwhash_str(outstr, pass, pass.bytesize, @ops, @mem) != 0
|
|
raise Sodium::Error.new("crypto_pwhash_str")
|
|
end
|
|
outstr
|
|
end
|
|
|
|
# Verify a password against a stored String.
|
|
# raises PasswordVerifyError on failure.
|
|
def verify(str, pass)
|
|
# BUG: verify str length
|
|
r = LibSodium.crypto_pwhash_str_verify(str, pass, pass.bytesize)
|
|
raise Error::Verify.new if r != 0
|
|
self
|
|
end
|
|
|
|
# Check if a password verification string str matches the parameters ops and mem, and the current default algorithm.
|
|
def needs_rehash?(str) : Bool
|
|
# BUG: verify str length
|
|
case LibSodium.crypto_pwhash_str_needs_rehash(str, @ops, @mem)
|
|
when 0
|
|
false
|
|
when 1
|
|
true
|
|
else
|
|
raise Sodium::Error.new("crypto_pwhash_str_needs_rehash")
|
|
end
|
|
end
|
|
end
|
|
end
|