You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

48 lines
1.5 KiB
Common Lisp

(in-package :cl-password)
(defparameter *prng* (make-prng :fortuna :seed :urandom))
(defun make-random-salt (&optional (size 16))
(random-data size *prng*))
(defun generate-password-hash-scrypt (password salt hash-length n r p)
(byte-array-to-hex-string
(derive-key
(make-kdf 'scrypt-kdf :n n :r r :p p)
(ascii-string-to-byte-array password)
salt
0 ; ignored for scrypt
hash-length)))
(define-condition unsupported-hash-error (error)
((name :initarg :name :reader name)))
(defun hash-password
(password type
&key (hash-length 40)
(n 2048) (r 1) (p 1)
(salt (make-random-salt)))
(when (typep salt 'string) (setf salt (hex-string-to-byte-array salt)))
(cond ((eq type :scrypt)
(list :type type
:salt (byte-array-to-hex-string salt)
:n n
:r r
:p p
:hash-length hash-length
:hash (generate-password-hash-scrypt password salt hash-length n r p)))
(t (error 'unsupported-hash-error :name type))))
(defun check-password (password hashed-password-plist)
(equalp
(getf
(hash-password password
(getf hashed-password-plist :type)
:hash-length (getf hashed-password-plist :hash-length)
:n (getf hashed-password-plist :n)
:r (getf hashed-password-plist :r)
:p (getf hashed-password-plist :p)
:salt (getf hashed-password-plist :salt))
:hash)
(getf hashed-password-plist :hash)))