Skip to content

Instantly share code, notes, and snippets.

@jcromartie
Created October 21, 2011 17:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcromartie/3bac44cdcdbb27fbb75b to your computer and use it in GitHub Desktop.
Save jcromartie/3bac44cdcdbb27fbb75b to your computer and use it in GitHub Desktop.
(defmulti sha-1
{:arglists '([x])}
type)
(defmethod sha-1 InputStream
[stream]
(let [md (MessageDigest/getInstance "SHA1")
md-stream (DigestInputStream. stream md)
buffer (byte-array 1024)
stream-read #(.read md-stream buffer)]
(loop [res (stream-read)]
(when (<= 0 res)
(recur (stream-read))))
(.digest md)))
;; for byte arrays
(defmethod sha-1 (Class/forName "[B")
[bytes]
(sha-1 (ByteArrayInputStream. bytes)))
(defmethod sha-1 String
[s]
(sha-1 (.getBytes s)))
;; salted iterated password hashing
(def *pw-hash-factor* 5000)
(def *prng* (java.util.Random. (System/currentTimeMillis)))
(defn gen-salt
"Generates a hex string from random bytes"
[]
(let [buffer (byte-array 8)]
(.nextBytes *prng* buffer)
(hex-str buffer)))
(defn hash-pw
"Return salted hash string for password, using *pw-hash-factor* iterations"
([pw salt iterations]
(let [salt-bytes (.getBytes salt)
hash-seq (iterate #(let [bytes (concat % salt-bytes)]
(sha-1 (byte-array (count bytes) bytes)))
(.getBytes pw))
hash-str (hex-str (nth hash-seq iterations))]
(str hash-str "|" salt "|" iterations)))
([pw]
(hash-pw pw (gen-salt) *pw-hash-factor*)))
(defn check-pw
"Check if password is valid given salted hash string"
[pw pw-hash]
(let [[_ salt iterations-str] (.split pw-hash "\\|")
iterations (Integer/parseInt iterations-str)]
(= pw-hash (hash-pw pw salt iterations))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment