| License | MIT |
|---|---|
| Safe Haskell | None |
| Language | Haskell2010 |
Data.OTP
Description
Implements the HMAC-Based One-Time Password Algorithm (HOTP) as defined in RFC 4226 and the Time-Based One-Time Password Algorithm (TOTP) as defined in RFC 6238.
Many operations in this module take or return a Word32 OTP value
(whose most significant bit is always 0) which is truncated modulo
10^digits according to the Word8 digits
parameter. Consequently, passing a value above 10 won't produce
more than 10 digits and will effectively return the raw
non-truncated 31-bit OTP value.
Since: OTP-0.1.0.0
Synopsis
- hotp :: HashAlgorithm -> Secret -> Word64 -> Word8 -> Word32
- hotpCheck :: HashAlgorithm -> Secret -> (Word8, Word8) -> Word64 -> Word8 -> Word32 -> Bool
- totp :: HashAlgorithm -> Secret -> UTCTime -> Word64 -> Word8 -> Word32
- totpCheck :: HashAlgorithm -> Secret -> (Word8, Word8) -> UTCTime -> Word64 -> Word8 -> Word32 -> Bool
- totpCounter :: UTCTime -> Word64 -> Word64
- counterRange :: (Word8, Word8) -> Word64 -> [Word64]
- totpCounterRange :: (Word8, Word8) -> UTCTime -> Word64 -> [Word64]
- data HashAlgorithm
- type Secret = ByteString
HOTP
Arguments
| :: HashAlgorithm | Hashing algorithm |
| -> Secret | Shared secret |
| -> Word64 | Counter value |
| -> Word8 | Number of base10 digits in HOTP value |
| -> Word32 | HOTP value |
Compute HMAC-Based One-Time Password using secret key and counter value.
>>>hotp SHA1 "1234" 100 6317569
>>>hotp SHA512 "1234" 100 6134131
>>>hotp SHA512 "1234" 100 855134131
Arguments
| :: HashAlgorithm | Hash algorithm to use |
| -> Secret | Shared secret |
| -> (Word8, Word8) | Valid counter range, before and after ideal |
| -> Word64 | Ideal (expected) counter value |
| -> Word8 | Number of base10 digits in a password |
| -> Word32 | Password (i.e. HOTP value) entered by user |
| -> Bool | True if password is valid |
Check presented password against a valid range.
>>>hotp SHA1 "1234" 10 650897
>>>hotpCheck SHA1 "1234" (0,0) 10 6 50897True
>>>hotpCheck SHA1 "1234" (0,0) 9 6 50897False
>>>hotpCheck SHA1 "1234" (0,1) 9 6 50897True
>>>hotpCheck SHA1 "1234" (1,0) 11 6 50897True
>>>hotpCheck SHA1 "1234" (2,2) 8 6 50897True
>>>hotpCheck SHA1 "1234" (2,2) 7 6 50897False
>>>hotpCheck SHA1 "1234" (2,2) 12 6 50897True
>>>hotpCheck SHA1 "1234" (2,2) 13 6 50897False
TOTP
Arguments
| :: HashAlgorithm | Hash algorithm to use |
| -> Secret | Shared secret |
| -> UTCTime | Time of TOTP |
| -> Word64 | Time range in seconds |
| -> Word8 | Number of base10 digits in TOTP value |
| -> Word32 | TOTP value |
Compute a Time-Based One-Time Password using secret key and time.
>>>totp SHA1 "1234" (read "2010-10-10 00:01:00 UTC") 30 6388892
>>>totp SHA1 "1234" (read "2010-10-10 00:01:00 UTC") 30 843388892
>>>totp SHA1 "1234" (read "2010-10-10 00:01:15 UTC") 30 843388892
>>>totp SHA1 "1234" (read "2010-10-10 00:01:31 UTC") 30 839110359
Arguments
| :: HashAlgorithm | Hash algorithm to use |
| -> Secret | Shared secret |
| -> (Word8, Word8) | Valid counter range, before and after ideal |
| -> UTCTime | Time of TOTP |
| -> Word64 | Time range in seconds |
| -> Word8 | Number of base10 digits in a password |
| -> Word32 | Password given by user |
| -> Bool | True if password is valid |
Check presented password against time periods.
>>>totp SHA1 "1234" (read "2010-10-10 00:00:00 UTC") 30 6778374
>>>totpCheck SHA1 "1234" (0, 0) (read "2010-10-10 00:00:00 UTC") 30 6 778374True
>>>totpCheck SHA1 "1234" (0, 0) (read "2010-10-10 00:00:30 UTC") 30 6 778374False
>>>totpCheck SHA1 "1234" (1, 0) (read "2010-10-10 00:00:30 UTC") 30 6 778374True
>>>totpCheck SHA1 "1234" (1, 0) (read "2010-10-10 00:01:00 UTC") 30 6 778374False
>>>totpCheck SHA1 "1234" (2, 0) (read "2010-10-10 00:01:00 UTC") 30 6 778374True
Auxiliary
Calculate HOTP counter using time. Starting time (T0 according to RFC6238) is 0 (begining of UNIX epoch)
>>>totpCounter (read "2010-10-10 00:00:00 UTC") 3042888960
>>>totpCounter (read "2010-10-10 00:00:30 UTC") 3042888961
>>>totpCounter (read "2010-10-10 00:01:00 UTC") 3042888962
Arguments
| :: (Word8, Word8) | Number of counters before and after ideal |
| -> Word64 | Ideal counter value |
| -> [Word64] |
Make a sequence of acceptable counters, protected from arithmetic overflow.
>>>counterRange (0, 0) 9000[9000]
>>>counterRange (1, 0) 9000[8999,9000]
>>>length $ counterRange (5000, 0) 9000501
>>>length $ counterRange (5000, 5000) 90001000
>>>counterRange (2, 2) maxBound[18446744073709551613,18446744073709551614,18446744073709551615]
>>>counterRange (2, 2) minBound[0,1,2]
>>>counterRange (2, 2) (maxBound `div` 2)[9223372036854775805,9223372036854775806,9223372036854775807,9223372036854775808,9223372036854775809]
>>>counterRange (5, 5) 9000[8995,8996,8997,8998,8999,9000,9001,9002,9003,9004,9005]
RFC recommends avoiding excessively large values for counter ranges.
totpCounterRange :: (Word8, Word8) -> UTCTime -> Word64 -> [Word64] Source #
Make a sequence of acceptable periods.
>>>totpCounterRange (0, 0) (read "2010-10-10 00:01:00 UTC") 30[42888962]
>>>totpCounterRange (2, 0) (read "2010-10-10 00:01:00 UTC") 30[42888960,42888961,42888962]
>>>totpCounterRange (0, 2) (read "2010-10-10 00:01:00 UTC") 30[42888962,42888963,42888964]
>>>totpCounterRange (2, 2) (read "2010-10-10 00:01:00 UTC") 30[42888960,42888961,42888962,42888963,42888964]
data HashAlgorithm Source #
Hash algorithm used for HOTP/TOTP computations
Instances
| Eq HashAlgorithm Source # | |
Defined in HashImpl Methods (==) :: HashAlgorithm -> HashAlgorithm -> Bool # (/=) :: HashAlgorithm -> HashAlgorithm -> Bool # | |
| Show HashAlgorithm Source # | |
Defined in HashImpl Methods showsPrec :: Int -> HashAlgorithm -> ShowS # show :: HashAlgorithm -> String # showList :: [HashAlgorithm] -> ShowS # | |
type Secret = ByteString Source #
Shared secret encoded as raw octets