mirror of
https://github.com/RobThree/TwoFactorAuth.git
synced 2026-08-20 20:12:46 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f546c73537 | |||
| c94fcd83d8 | |||
| 856167c950 |
@@ -81,7 +81,7 @@ When outputting a QR-code you can choose a `$label` for the user (which, when en
|
||||
|
||||
### Step 2: Verify secret shared key
|
||||
|
||||
When the code is added to the app, the app will be ready to start generating codes which 'expire' each '`$period`' number of seconds. To make sure the secret was entered, or scanned, correctly you need to verify this by having the user enter a generated code. To check if the generated code is valid you call the `verifyCode()` method:
|
||||
When the shared secret is added to the app, the app will be ready to start generating codes which 'expire' each '`$period`' number of seconds. To make sure the secret was entered, or scanned, correctly you need to verify this by having the user enter a generated code. To check if the generated code is valid you call the `verifyCode()` method:
|
||||
|
||||
````php
|
||||
// Verify code
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
<Compile Include="lib\Providers\Qr\QRException.php" />
|
||||
<Compile Include="lib\Providers\Qr\QRicketProvider.php" />
|
||||
<Compile Include="lib\Providers\Qr\QRServerProvider.php" />
|
||||
<Compile Include="lib\Providers\Rng\CSRNGProvider.php" />
|
||||
<Compile Include="lib\Providers\Rng\IRNGProvider.php" />
|
||||
<Compile Include="lib\Providers\Rng\MCryptRNGProvider.php" />
|
||||
<Compile Include="lib\Providers\Rng\OpenSSLRNGProvider.php" />
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "robthree/twofactorauth",
|
||||
"description": "Two Factor Authentication",
|
||||
"version": "1.3",
|
||||
"version": "1.4",
|
||||
"type": "library",
|
||||
"keywords": [ "Authentication", "Two Factor Authentication", "Multi Factor Authentication", "TFA", "MFA", "PHP", "Authenticator", "Authy" ],
|
||||
"homepage": "https://github.com/RobThree/TwoFactorAuth",
|
||||
|
||||
@@ -43,6 +43,7 @@ class QRServerProvider extends BaseHTTPQRCodeProvider
|
||||
case 'eps':
|
||||
return 'application/postscript';
|
||||
}
|
||||
throw new QRException(sprintf('Unknown MIME-type: %s', $this->format));
|
||||
}
|
||||
|
||||
public function getQRCodeImage($qrtext, $size)
|
||||
|
||||
@@ -33,6 +33,7 @@ class QRicketProvider extends BaseHTTPQRCodeProvider
|
||||
case 'j':
|
||||
return 'image/jpeg';
|
||||
}
|
||||
throw new QRException(sprintf('Unknown MIME-type: %s', $this->format));
|
||||
}
|
||||
|
||||
public function getQRCodeImage($qrtext, $size)
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace RobThree\Auth\Providers\Rng;
|
||||
|
||||
class CSRNGProvider implements IRNGProvider
|
||||
{
|
||||
public function getRandomBytes($bytecount) {
|
||||
return random_bytes($bytecount); // PHP7+
|
||||
}
|
||||
|
||||
public function isCryptographicallySecure() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,9 @@ class TwoFactorAuth
|
||||
|
||||
// Try to find best available RNG provider if none was specified
|
||||
if ($rngprovider==null) {
|
||||
if (function_exists('mcrypt_create_iv')) {
|
||||
if (function_exists('random_bytes')) {
|
||||
$rngprovider = new Providers\Rng\CSRNGProvider();
|
||||
} elseif (function_exists('mcrypt_create_iv')) {
|
||||
$rngprovider = new Providers\Rng\MCryptRNGProvider();
|
||||
} elseif (function_exists('openssl_random_pseudo_bytes')) {
|
||||
$rngprovider = new Providers\Rng\OpenSSLRNGProvider();
|
||||
|
||||
@@ -8,6 +8,7 @@ require_once 'lib/Providers/Qr/GoogleQRCodeProvider.php';
|
||||
|
||||
require_once 'lib/Providers/Rng/IRNGProvider.php';
|
||||
require_once 'lib/Providers/Rng/RNGException.php';
|
||||
require_once 'lib/Providers/Rng/CSRNGProvider.php';
|
||||
require_once 'lib/Providers/Rng/MCryptRNGProvider.php';
|
||||
require_once 'lib/Providers/Rng/OpenSSLRNGProvider.php';
|
||||
require_once 'lib/Providers/Rng/HashRNGProvider.php';
|
||||
@@ -24,7 +25,7 @@ class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testConstructorThrowsOnInvalidDigits() {
|
||||
|
||||
$tfa = new TwoFactorAuth('Test', 0);
|
||||
new TwoFactorAuth('Test', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,7 +33,7 @@ class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testConstructorThrowsOnInvalidPeriod() {
|
||||
|
||||
$tfa = new TwoFactorAuth('Test', 6, 0);
|
||||
new TwoFactorAuth('Test', 6, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,7 +41,7 @@ class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testConstructorThrowsOnInvalidAlgorithm() {
|
||||
|
||||
$tfa = new TwoFactorAuth('Test', 6, 30, 'xxx');
|
||||
new TwoFactorAuth('Test', 6, 30, 'xxx');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,7 +49,7 @@ class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testConstructorThrowsOnQrProviderNotImplementingInterface() {
|
||||
|
||||
$tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', new stdClass());
|
||||
new TwoFactorAuth('Test', 6, 30, 'sha1', new stdClass());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +57,7 @@ class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testConstructorThrowsOnRngProviderNotImplementingInterface() {
|
||||
|
||||
$tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, new stdClass());
|
||||
new TwoFactorAuth('Test', 6, 30, 'sha1', null, new stdClass());
|
||||
}
|
||||
|
||||
public function testGetCodeReturnsCorrectResults() {
|
||||
@@ -147,7 +148,7 @@ class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGetCodeThrowsOnInvalidBase32String1() {
|
||||
$tfa = new TwoFactorAuth('Test');
|
||||
$result = $tfa->getCode('FOO1BAR8BAZ9'); //1, 8 & 9 are invalid chars
|
||||
$tfa->getCode('FOO1BAR8BAZ9'); //1, 8 & 9 are invalid chars
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,7 +156,7 @@ class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGetCodeThrowsOnInvalidBase32String2() {
|
||||
$tfa = new TwoFactorAuth('Test');
|
||||
$result = $tfa->getCode('mzxw6==='); //Lowercase
|
||||
$tfa->getCode('mzxw6==='); //Lowercase
|
||||
}
|
||||
|
||||
public function testKnownBase32DecodeTestVectors() {
|
||||
@@ -242,7 +243,62 @@ class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('47863826', $tfa->getCode($secret, 20000000000));
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires function random_bytes
|
||||
*/
|
||||
public function testCSRNGProvidersReturnExpectedNumberOfBytes() {
|
||||
$rng = new \RobThree\Auth\Providers\Rng\CSRNGProvider();
|
||||
foreach ($this->getRngTestLengths() as $l)
|
||||
$this->assertEquals($l, strlen($rng->getRandomBytes($l)));
|
||||
$this->assertEquals(true, $rng->isCryptographicallySecure());
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires function hash_algos
|
||||
* @requires function hash
|
||||
*/
|
||||
public function testHashRNGProvidersReturnExpectedNumberOfBytes() {
|
||||
$rng = new \RobThree\Auth\Providers\Rng\HashRNGProvider();
|
||||
foreach ($this->getRngTestLengths() as $l)
|
||||
$this->assertEquals($l, strlen($rng->getRandomBytes($l)));
|
||||
$this->assertEquals(false, $rng->isCryptographicallySecure());
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires function mcrypt_create_iv
|
||||
*/
|
||||
public function testMCryptRNGProvidersReturnExpectedNumberOfBytes() {
|
||||
$rng = new \RobThree\Auth\Providers\Rng\MCryptRNGProvider();
|
||||
foreach ($this->getRngTestLengths() as $l)
|
||||
$this->assertEquals($l, strlen($rng->getRandomBytes($l)));
|
||||
$this->assertEquals(true, $rng->isCryptographicallySecure());
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires function openssl_random_pseudo_bytes
|
||||
*/
|
||||
public function testStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes() {
|
||||
$rng = new \RobThree\Auth\Providers\Rng\OpenSSLRNGProvider(true);
|
||||
foreach ($this->getRngTestLengths() as $l)
|
||||
$this->assertEquals($l, strlen($rng->getRandomBytes($l)));
|
||||
$this->assertEquals(true, $rng->isCryptographicallySecure());
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires function openssl_random_pseudo_bytes
|
||||
*/
|
||||
public function testNonStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes() {
|
||||
$rng = new \RobThree\Auth\Providers\Rng\OpenSSLRNGProvider(false);
|
||||
foreach ($this->getRngTestLengths() as $l)
|
||||
$this->assertEquals($l, strlen($rng->getRandomBytes($l)));
|
||||
$this->assertEquals(false, $rng->isCryptographicallySecure());
|
||||
}
|
||||
|
||||
|
||||
private function getRngTestLengths() {
|
||||
return array(1, 16, 32, 256);
|
||||
}
|
||||
|
||||
private function DecodeDataUri($datauri) {
|
||||
if (preg_match('/data:(?P<mimetype>[\w\.\-\/]+);(?P<encoding>\w+),(?P<data>.*)/', $datauri, $m) === 1) {
|
||||
return array(
|
||||
|
||||
Reference in New Issue
Block a user