diff options
author | RobThree <rob@devcorner.nl> | 2014-09-19 01:24:52 +0200 |
---|---|---|
committer | RobThree <rob@devcorner.nl> | 2014-09-19 01:24:52 +0200 |
commit | 70c3a190b7ed56a65562d3abc09c7c4766f19b0f (patch) | |
tree | df904b1ee74d595c1527ae5cea748370ca1c507b | |
parent | 56dcfc48e210180d358cd8b1672559067b66e8d1 (diff) | |
download | TwoFactorAuth-70c3a190b7ed56a65562d3abc09c7c4766f19b0f.zip TwoFactorAuth-70c3a190b7ed56a65562d3abc09c7c4766f19b0f.tar.gz TwoFactorAuth-70c3a190b7ed56a65562d3abc09c7c4766f19b0f.tar.bz2 |
* Actually use $qrcodeprovider parameter from constructor
* Use array_flip instead of for-loop
* Also tested on PHP 5.3
* Demo page is now some 'actual' HTML and text cleaned up a little
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | demo.php | 43 | ||||
-rw-r--r-- | src/TwoFactorAuth.php | 8 |
3 files changed, 28 insertions, 25 deletions
@@ -4,7 +4,7 @@ PHP class for two-factor authorization using [TOTP](http://en.wikipedia.org/wiki ## Requirements -* Tested on PHP5.4 +* Tested on PHP 5.3 and 5.4 * [cURL](http://php.net/manual/en/book.curl.php) when using the default `GoogleQRCodeProvider` but you can provide your own QR-code provider. @@ -1,20 +1,25 @@ -<?php -error_reporting(-1); -require_once 'src/TwoFactorAuth.php'; - -$tfa = new TwoFactorAuth('MyApp'); +<!doctype html> +<html> +<head> + <title>Demo</title> +</head> +<body> + <ul> + <?php + error_reporting(-1); + require_once 'src/TwoFactorAuth.php'; -$secret = $tfa->createSecret(); -echo 'First create a secret and associate it with a user: ' . $secret . ' (keep this code private; do not share it with the user or anyone, just store it in your database or something)<br>'; - -echo 'Next create a QR code and let the user scan it:<br>'; - -$label = 'My label'; -echo 'Image:<br><img src="' . $tfa->getQRCodeImageAsDataUri($label, $secret) . '"><br>'; - -$code = $tfa->getCode($secret); -echo 'Next, have the user verify the code; at this time the code displayed by a 2FA-app would be: <span style="color:#00c">' . $code . '</span> (but that changes periodically)<br>'; - -echo 'When the code checks out, 2FA can be / is enabled; store secret with user (encrypted?) and have the user verify a code each time a new session is started.<br>'; -echo 'When aforementioned code was entered, the result would be: ' . (($tfa->verifyCode($secret, $code) === true) ? '<span style="color:#0c0">OK</span>' : '<span style="color:#c00">FAIL</span>') . '<br>'; -echo 'Make sure server-time is NTP-synced!<br>';
\ No newline at end of file + $tfa = new TwoFactorAuth('MyApp'); + + $secret = $tfa->createSecret(); + echo '<li>First create a secret and associate it with a user: ' . $secret . ' (keep this code private; do not share it with the user or anyone else)'; + echo '<li>Next create a QR code and let the user scan it:<br><img src="' . $tfa->getQRCodeImageAsDataUri('My label', $secret) . '">'; + $code = $tfa->getCode($secret); + echo '<li>Next, have the user verify the code; at this time the code displayed by a 2FA-app would be: <span style="color:#00c">' . $code . '</span> (but that changes periodically)'; + echo '<li>When the code checks out, 2FA can be / is enabled; store secret with user (encrypted?) and have the user verify a code each time a new session is started.'; + echo '<li>When aforementioned code (' . $code . ') was entered, the result would be: ' . (($tfa->verifyCode($secret, $code) === true) ? '<span style="color:#0c0">OK</span>' : '<span style="color:#c00">FAIL</span>'); + echo '<li>Make sure server-time is NTP-synced!'; + ?> + </ul> +</body> +</html> diff --git a/src/TwoFactorAuth.php b/src/TwoFactorAuth.php index ab86eba..5c2ce84 100644 --- a/src/TwoFactorAuth.php +++ b/src/TwoFactorAuth.php @@ -34,11 +34,10 @@ class TwoFactorAuth { if (!($qrcodeprovider instanceof IQRCodeProvider)) throw new Exception('QRCodeProvider must implement IQRCodeProvider'); - $this->qrcodeprovider = new GoogleQRCodeProvider(); + $this->qrcodeprovider = $qrcodeprovider; self::$_base32 = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567='); - for ($i = 0; $i < sizeof(self::$_base32); $i++) - self::$_base32lookup[self::$_base32[$i]] = $i; + self::$_base32lookup = array_flip(self::$_base32); } /** @@ -61,8 +60,7 @@ class TwoFactorAuth { $ts = "\0\0\0\0".pack('N*', $this->getTimeSlice($this->getTime($time))); // Pack time into binary string $hm = hash_hmac($this->algorithm, $ts, $secretkey, true); // Hash it with users secret key - $offset = ord(substr($hm, -1)) & 0x0F; // Use last nibble of result as index/offset - $hashpart = substr($hm, $offset, 4); // Grab 4 bytes of the result + $hashpart = substr($hm, ord(substr($hm, -1)) & 0x0F, 4); // Use last nibble of result as index/offset and grab 4 bytes of the result $value = unpack('N', $hashpart); // Unpack binary value $value = $value[1] & 0x7FFFFFFF; // Drop MSB, keep only 31 bits |