mirror of
https://github.com/RobThree/TwoFactorAuth.git
synced 2026-08-30 12:06:59 +00:00
* Added isCryptographicallySecure to IRNGProvider interface
* Exceptions thrown by TwoFactorAuth are now of type TwoFactorAuthException * createSecret now has extra argument $requirecryptosecure which is used to force cryptographically secure secrets * HashRNGProvider now returns string instead of "byte array" * HashRNGProvider is now initialized with two random values (for the heck of it...)
This commit is contained in:
@@ -13,11 +13,16 @@ class HashRNGProvider implements IRNGProvider
|
||||
}
|
||||
|
||||
public function getRandomBytes($bytecount) {
|
||||
$result = array();
|
||||
$result = '';
|
||||
$hash = mt_rand();
|
||||
for ($i = 0; $i < $bytecount; $i++) {
|
||||
$hash = hash($this->algorithm, $hash.mt_rand(), true);
|
||||
array_push($result, $hash[mt_rand(0, sizeof($hash))]);
|
||||
$result .= $hash[mt_rand(0, sizeof($hash))];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function isCryptographicallySecure() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,4 +5,5 @@ namespace RobThree\TwoFactorAuth\Providers\Rng;
|
||||
interface IRNGProvider
|
||||
{
|
||||
public function getRandomBytes($bytecount);
|
||||
public function isCryptographicallySecure();
|
||||
}
|
||||
@@ -16,4 +16,8 @@ class MCryptRNGProvider implements IRNGProvider
|
||||
throw new RNGException('mcrypt_create_iv returned an invalid value');
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function isCryptographicallySecure() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -18,4 +18,8 @@ class OpenSSLRNGProvider implements IRNGProvider
|
||||
throw new RNGException('openssl_random_pseudo_bytes returned an invalid value');
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function isCryptographicallySecure() {
|
||||
return $this->requirestrong;
|
||||
}
|
||||
}
|
||||
@@ -21,16 +21,16 @@ class TwoFactorAuth
|
||||
$this->issuer = $issuer;
|
||||
|
||||
if (!is_int($digits) || $digits <= 0)
|
||||
throw new Exception('Digits must be int > 0');
|
||||
throw new TwoFactorAuthException('Digits must be int > 0');
|
||||
$this->digits = $digits;
|
||||
|
||||
if (!is_int($period) || $period <= 0)
|
||||
throw new Exception('Period must be int > 0');
|
||||
throw new TwoFactorAuthException('Period must be int > 0');
|
||||
$this->period = $period;
|
||||
|
||||
$algorithm = strtolower(trim($algorithm));
|
||||
if (!in_array($algorithm, self::$_supportedalgos))
|
||||
throw new Exception('Unsupported algorithm: ' . $algorithm);
|
||||
throw new TwoFactorAuthException('Unsupported algorithm: ' . $algorithm);
|
||||
$this->algorithm = $algorithm;
|
||||
|
||||
// Set default QR Code provider if none was specified
|
||||
@@ -38,7 +38,7 @@ class TwoFactorAuth
|
||||
$qrcodeprovider = new Providers\Qr\GoogleQRCodeProvider();
|
||||
|
||||
if (!($qrcodeprovider instanceof Providers\Qr\IQRCodeProvider))
|
||||
throw new Exception('QRCodeProvider must implement IQRCodeProvider');
|
||||
throw new TwoFactorAuthException('QRCodeProvider must implement IQRCodeProvider');
|
||||
|
||||
$this->qrcodeprovider = $qrcodeprovider;
|
||||
|
||||
@@ -54,7 +54,7 @@ class TwoFactorAuth
|
||||
}
|
||||
|
||||
if (!($rngprovider instanceof Providers\Rng\IRNGProvider))
|
||||
throw new Exception('RNGProvider must implement IRNGProvider');
|
||||
throw new TwoFactorAuthException('RNGProvider must implement IRNGProvider');
|
||||
|
||||
$this->rngprovider = $rngprovider;
|
||||
|
||||
@@ -65,10 +65,12 @@ class TwoFactorAuth
|
||||
/**
|
||||
* Create a new secret
|
||||
*/
|
||||
public function createSecret($bits = 80)
|
||||
public function createSecret($bits = 80, $requirecryptosecure = true)
|
||||
{
|
||||
$secret = '';
|
||||
$bytes = ceil($bits / 5); //We use 5 bits of each byte (since we have a 32-character 'alphabet' / BASE32)
|
||||
if ($requirecryptosecure && !$this->rngprovider->isCryptographicallySecure())
|
||||
throw new TwoFactorAuthException('RNG provider is not cryptographically secure');
|
||||
$rnd = $this->rngprovider->getRandomBytes($bytes);
|
||||
for ($i = 0; $i < $bytes; $i++)
|
||||
$secret .= self::$_base32[ord($rnd[$i]) & 31]; //Mask out left 3 bits for 0-31 values
|
||||
@@ -112,7 +114,7 @@ class TwoFactorAuth
|
||||
public function getQRCodeImageAsDataUri($label, $secret, $size = 200)
|
||||
{
|
||||
if (!is_int($size) || $size < 0)
|
||||
throw new Exception('Size must be int > 0');
|
||||
throw new TwoFactorAuthException('Size must be int > 0');
|
||||
|
||||
return 'data:'
|
||||
. $this->qrcodeprovider->getMimeType()
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace RobThree\TwoFactorAuth;
|
||||
|
||||
class TwoFactorAuthException extends \Exception
|
||||
{
|
||||
function __construct($message = "", $code = 0, $exception = null)
|
||||
{
|
||||
parent::__construct($message, $code, $exception);
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@
|
||||
<Compile Include="RobThree\TwoFactorAuth\TwoFactorAuth.php" />
|
||||
<Compile Include=".gitignore" />
|
||||
<Compile Include="README.md" />
|
||||
<Compile Include="RobThree\TwoFactorAuth\TwoFactorAuthException.php" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="RobThree\" />
|
||||
|
||||
Reference in New Issue
Block a user