Compare commits
3 Commits
e32e054c8c
...
e165dc107f
| Author | SHA1 | Date | |
|---|---|---|---|
| e165dc107f | |||
| e18953b287 | |||
| 290c52a71f |
3
src/totp/app.clj
Normal file
3
src/totp/app.clj
Normal file
@@ -0,0 +1,3 @@
|
||||
(ns totp.app
|
||||
( :require [totp.core :refer :all]))
|
||||
|
||||
@@ -71,15 +71,17 @@
|
||||
|
||||
(defn get-otp
|
||||
"Generate an OTP with the given secret (in base32) for the specified timestep"
|
||||
[secret step]
|
||||
(when (and secret step)
|
||||
(let [k (b32/decode secret)
|
||||
c (long->bytes step)
|
||||
hs (hmac-sha1 k c)
|
||||
offset (bit-and (get hs (dec (count hs))) 0x0f) ;; int offset = hs[hs.length-1] & 0xf;
|
||||
chunk (Arrays/copyOfRange hs offset (+ offset 4)) ;(take 4 (drop offset hs)) ;; byte[] chunk = Arrays.copyOfRange(hs, offset, offset+4)
|
||||
]
|
||||
(format "%6d" (-> chunk
|
||||
(bytes->int)
|
||||
(bit-and 0x7fffffff)
|
||||
(rem 1000000))))))
|
||||
([secret step]
|
||||
(when (and secret step)
|
||||
(let [k (b32/decode secret)
|
||||
c (long->bytes step)
|
||||
hs (hmac-sha1 k c)
|
||||
offset (bit-and (get hs (dec (count hs))) 0x0f) ;; int offset = hs[hs.length-1] & 0xf;
|
||||
chunk (Arrays/copyOfRange hs offset (+ offset 4)) ;(take 4 (drop offset hs)) ;; byte[] chunk = Arrays.copyOfRange(hs, offset, offset+4)
|
||||
]
|
||||
(format "%06d" (-> chunk
|
||||
(bytes->int)
|
||||
(bit-and 0x7fffffff)
|
||||
(rem 1000000))))))
|
||||
([secret]
|
||||
(get-otp secret (timestamp->steps (System/currentTimeMillis) 30))))
|
||||
|
||||
@@ -67,4 +67,5 @@
|
||||
(is (nil? (get-otp nil "")))
|
||||
(is (nil? (get-otp nil 1000))))
|
||||
(testing "Common usage"
|
||||
(is (= "837552" (get-otp "MJXW42LBORXQ====" 10000)))))
|
||||
(is (= "837552" (get-otp "MJXW42LBORXQ====" 10000)))
|
||||
(is (= 6 (count (get-otp "MJXW42LBORXQ===="))))))
|
||||
Reference in New Issue
Block a user