Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements to crypto-password. #1

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/crypto/password/hmac.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
(ns crypto.password.hmac
"Functions for calculating HMAC using multiple crypto hash functions."
(:refer-clojure :exclude [bytes hash])
(:require [crypto.equality :as crypto])
(:import javax.crypto.Mac
javax.crypto.spec.SecretKeySpec
org.apache.commons.codec.binary.Hex))

(def ^{:private true :doc "Standard crypto hash functions for MAC."}
hash {:hmacmd5 "HMACMD5"
:hmacsha1 "HMACSHA1"
:hmacsha256 "HMACSHA256"
:hmacsha384 "HMACSHA384"
:hmacsha512 "HMACSHA512"})


(defn- bytes
"Convert a String to a byte-array."
[^String s]
(.getBytes s "UTF-8"))


(defn hmac
"Compute HMAC of `msg` given secret key `k`.
Optionally pass in the algorithm to be used for computing HMAC (defaults to :hmacsha1).
Valid options are :hmacmd5, :hmacsha1, :hmacsha256, :hmac384 & :hmacsha512."
([k msg]
(hmac k msg :hmacsha1))
([k msg algo]
(if-let [algo* (hash algo)]
(let [key-spec (SecretKeySpec. (bytes k) algo*)
mac (.doFinal (doto (Mac/getInstance algo*) (.init key-spec))
(bytes msg))]
(Hex/encodeHexString mac))
(throw (IllegalArgumentException.
(format "Incorrect hash algorithm %s specified. Valid choices are %s."
algo (keys hash)))))))


(defn check
"Check if the given HMAC is correct given the key & algorithm.
Optionally pass in the algorithm to be used for computing HMAC (defaults to :hmacsha1).
Valid options are :hmacmd5, :hmacsha1, :hmacsha256, :hmac384 & :hmacsha512."
([mac k original]
(check mac k original :hmacsha1))
([mac k original algo]
(crypto/eq? mac (hmac k original algo))))
2 changes: 1 addition & 1 deletion src/crypto/password/pbkdf2.clj
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

All elements in the output string are Base64 encoded."
([raw]
(encrypt raw 20000))
(encrypt raw 100000))
([raw iterations]
(encrypt raw iterations (random/bytes 8)))
([raw iterations salt]
Expand Down
27 changes: 27 additions & 0 deletions test/crypto/password/test/hmac.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
(ns crypto.password.test.hmac
(:use clojure.test)
(:require [crypto.password.hmac :as mac]))

(deftest test-hmac
(are [algo result] (= (mac/hmac "key" "The quick brown fox jumps over the lazy dog" algo) result)
:hmacmd5 "80070713463e7749b90c2dc24911e275"
:hmacsha1 "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
:hmacsha256 "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8"
:hmacsha384 "d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6fc592c5d3e1ae50700582a96cf35e1e554995fe4e03381c237"
:hmacsha512 "b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a")

(are [s] (mac/check (mac/hmac "foobar" s) "foobar" s)
"a"
"foo"
"password"
"Testing"
"Test123"
"ÁäñßOÔ"
"großpösna"
"Some rather long pass phrase perhaps out of a book or poem")

(are [s r] (not (mac/check (mac/hmac "foobar" s) "foobar" r))
"a" "b"
"a" "a "
"aaaaa" "aaaaa\n"
"großpösna" "grossposna"))