PluginProbe
Two Factor Authentication / 1.2.6
Two Factor Authentication v1.2.6
1.12.2 1.13.0 1.14.10 1.14.11 1.14.14 1.14.15 1.14.16 1.14.17 1.14.23 1.14.24 1.14.26 1.14.27 1.14.3 1.14.4 1.14.5 1.14.7 1.14.8 1.15.5 1.16.0 1.2.10 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 All 98 releases
two-factor-authentication / hotp-php-master / hotp.php

hotp.php in Two Factor Authentication 1.2.6, at hotp-php-master/hotp.php

175 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * HOTP Class
4 * Based on the work of OAuth, and the sample implementation of HMAC OTP
5 * http://tools.ietf.org/html/draft-mraihi-oath-hmac-otp-04#appendix-D
6 * @author Jakob Heuser (firstname)@felocity.com
7 * @copyright 2011
8 * @license BSD
9 * @version 1.0
10 */
11 class HOTP {
12 /**
13 * Generate a HOTP key based on a counter value (event based HOTP)
14 * @param string $key the key to use for hashing
15 * @param int $counter the number of attempts represented in this hashing
16 * @return HOTPResult a HOTP Result which can be truncated or output
17 */
18 public static function generateByCounter($key, $counter) {
19 // the counter value can be more than one byte long,
20 // so we need to pack it down properly.
21 $cur_counter = array(0, 0, 0, 0, 0, 0, 0, 0);
22 for($i = 7; $i >= 0; $i--) {
23 $cur_counter[$i] = pack ('C*', $counter);
24 $counter = $counter >> 8;
25 }
26
27 $bin_counter = implode($cur_counter);
28
29 // Pad to 8 chars
30 if (strlen($bin_counter) < 8) {
31 $bin_counter = str_repeat (chr(0), 8 - strlen ($bin_counter)) . $bin_counter;
32 }
33
34 // HMAC
35 $hash = hash_hmac('sha1', $bin_counter, $key);
36
37 return new HOTPResult($hash);
38 }
39
40 /**
41 * Generate a HOTP key based on a timestamp and window size
42 * @param string $key the key to use for hashing
43 * @param int $window the size of the window a key is valid for in seconds
44 * @param int $timestamp a timestamp to calculate for, defaults to time()
45 * @return HOTPResult a HOTP Result which can be truncated or output
46 */
47 public static function generateByTime($key, $window, $timestamp = false) {
48 if (!$timestamp && $timestamp !== 0) {
49 $timestamp = HOTP::getTime();
50 }
51
52 $counter = intval($timestamp / $window);
53
54 return HOTP::generateByCounter($key, $counter);
55 }
56
57 /**
58 * Generate a HOTP key collection based on a timestamp and window size
59 * all keys that could exist between a start and end time will be included
60 * in the returned array
61 * @param string $key the key to use for hashing
62 * @param int $window the size of the window a key is valid for in seconds
63 * @param int $min the minimum window to accept before $timestamp
64 * @param int $max the maximum window to accept after $timestamp
65 * @param int $timestamp a timestamp to calculate for, defaults to time()
66 * @return array of HOTPResult
67 */
68 public static function generateByTimeWindow($key, $window, $min = -1, $max = 1, $timestamp = false) {
69 if (!$timestamp && $timestamp !== 0) {
70 $timestamp = HOTP::getTime();
71 }
72
73 $counter = intval($timestamp / $window);
74 $window = range($min, $max);
75
76 $out = array();
77 for ($i = 0; $i < count($window); $i++) {
78 $shift_counter = $window[$i];
79 $out[$shift_counter] = HOTP::generateByCounter($key, $counter + $shift_counter);
80 }
81
82 return $out;
83 }
84
85 /**
86 * Gets the current time
87 * Ensures we are operating in UTC for the entire framework
88 * Restores the timezone on exit.
89 * @return int the current time
90 */
91 public static function getTime() {
92 return time(); // PHP's time is always UTC
93 }
94 }
95
96 /**
97 * The HOTPResult Class converts an HOTP item to various forms
98 * Supported formats include hex, decimal, string, and HOTP
99 * @author Jakob Heuser (firstname)@felocity.com
100 */
101 class HOTPResult {
102 protected $hash;
103 protected $binary;
104 protected $decimal;
105
106 /**
107 * Build an HOTP Result
108 * @param string $value the value to construct with
109 */
110 public function __construct($value) {
111 // store raw
112 $this->hash = $value;
113 }
114
115 /**
116 * Returns the string version of the HOTP
117 * @return string
118 */
119 public function toString() {
120 return $this->hash;
121 }
122
123 /**
124 * Returns the hex version of the HOTP
125 * @return string
126 */
127 public function toHex() {
128 if( !$this->hex )
129 {
130 $this->hex = dechex($this->toDec());
131 }
132 return $this->hex;
133 }
134
135 /**
136 * Returns the decimal version of the HOTP
137 * @return int
138 */
139 public function toDec() {
140 if( !$this->decimal )
141 {
142 // store calculate decimal
143 $hmac_result = array();
144
145 // Convert to decimal
146 foreach(str_split($this->hash,2) as $hex)
147 {
148 $hmac_result[] = hexdec($hex);
149 }
150
151 $offset = $hmac_result[19] & 0xf;
152
153 $this->decimal = (
154 (($hmac_result[$offset+0] & 0x7f) << 24 ) |
155 (($hmac_result[$offset+1] & 0xff) << 16 ) |
156 (($hmac_result[$offset+2] & 0xff) << 8 ) |
157 ($hmac_result[$offset+3] & 0xff)
158 );
159 }
160 return $this->decimal;
161 }
162
163 /**
164 * Returns the truncated decimal form of the HOTP
165 * @param int $length the length of the HOTP to return
166 * @return string
167 */
168 public function toHOTP($length) {
169 $str = str_pad($this->toDec(), $length, "0", STR_PAD_LEFT);
170 $str = substr($str, (-1 * $length));
171 return $str;
172 }
173
174 }
175