* 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:
RobThree
2015-03-17 12:19:38 +01:00
parent 5a8d76cd92
commit 8428b2d25a
7 changed files with 37 additions and 9 deletions
@@ -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;
}
}
+9 -7
View File
@@ -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);
}
}
+1
View File
@@ -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\" />