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.
		
		
		
		
		
			
	
	
		
			
				
					
						
							|  |  |  | (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))) |