Added additional password hashing functions
All checks were successful
Create Docker Image / Test Application (x86_64) (push) Successful in 33s
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 1m26s
Create Docker Image / Build Docker Image (arm64) (push) Successful in 3m36s
Create Docker Image / Final Docker Image Manifest (push) Successful in 11s
All checks were successful
Create Docker Image / Test Application (x86_64) (push) Successful in 33s
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 1m26s
Create Docker Image / Build Docker Image (arm64) (push) Successful in 3m36s
Create Docker Image / Final Docker Image Manifest (push) Successful in 11s
This commit is contained in:
@@ -6,7 +6,6 @@ use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
use App\Classes\LDAP\Attribute\Password\Base;
|
||||
use App\Classes\LDAP\Attribute;
|
||||
use App\Traits\MD5Updates;
|
||||
|
||||
@@ -28,41 +27,54 @@ final class Password extends Attribute
|
||||
continue;
|
||||
|
||||
$class = self::commands.preg_replace('/\.php$/','',$file);
|
||||
if ($helpers->count())
|
||||
$helpers->push('');
|
||||
|
||||
$helpers = $helpers
|
||||
->merge([$class::id()=>$class]);
|
||||
}
|
||||
|
||||
return $helpers;
|
||||
return $helpers->sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an LDAP password syntax {xxx}yyyyyy, this function will return the object for xxx
|
||||
*
|
||||
* @param string $password
|
||||
* @return Attribute\Password\Base|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function hash(string $password): ?Attribute\Password\Base
|
||||
{
|
||||
$m = [];
|
||||
preg_match('/^{([A-Z0-9]+)}(.*)$/',$password,$m);
|
||||
|
||||
$hash = Arr::get($m,1,'*clear*');
|
||||
|
||||
if (($potential=static::helpers()->filter(fn($hasher)=>str_starts_with($hasher::id(),$hash)))->count() > 1) {
|
||||
foreach ($potential as $item) {
|
||||
if ($item::subid($password))
|
||||
return new $item;
|
||||
}
|
||||
|
||||
throw new \Exception(sprintf('Couldnt figure out a password hash for %s',$password));
|
||||
|
||||
} elseif (! $potential->count()) {
|
||||
throw new \Exception(sprintf('Couldnt figure out a password hash for %s',$password));
|
||||
}
|
||||
|
||||
return new ($potential->pop());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the object that will process a password
|
||||
*
|
||||
* @param string $id
|
||||
* @return Base|null
|
||||
* @return Attribute\Password\Base|null
|
||||
*/
|
||||
public static function hash(string $id): ?Attribute\Password\Base
|
||||
public static function hash_id(string $id): ?Attribute\Password\Base
|
||||
{
|
||||
return ($helpers=static::helpers())->has($id) ? new ($helpers->get($id)) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an LDAP password syntax {xxx}yyyyyy, this function will return xxx
|
||||
*
|
||||
* @param string $password
|
||||
* @return string
|
||||
*/
|
||||
public static function hash_id(string $password): string
|
||||
{
|
||||
$m = [];
|
||||
preg_match('/^{([A-Z]+)}(.*)$/',$password,$m);
|
||||
|
||||
return Arr::get($m,1,'Clear');
|
||||
}
|
||||
|
||||
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View
|
||||
{
|
||||
return view('components.attribute.password')
|
||||
@@ -75,11 +87,17 @@ final class Password extends Attribute
|
||||
|
||||
public function render_item_old(int $key): ?string
|
||||
{
|
||||
return Arr::get($this->oldValues,$key) ? str_repeat('x',8) : NULL;
|
||||
$pw = Arr::get($this->oldValues,$key);
|
||||
return $pw
|
||||
? (((($x=$this->hash($pw)) && ($x::id() !== '*clear*')) ? sprintf('{%s}',$x::shortid()) : '').str_repeat('*',16))
|
||||
: NULL;
|
||||
}
|
||||
|
||||
public function render_item_new(int $key): ?string
|
||||
{
|
||||
return Arr::get($this->values,$key) ? str_repeat('x',8) : NULL;
|
||||
$pw = Arr::get($this->values,$key);
|
||||
return $pw
|
||||
? (((($x=$this->hash($pw)) && ($x::id() !== '*clear*')) ? sprintf('{%s}',$x::shortid()) : '').str_repeat('*',16))
|
||||
: NULL;
|
||||
}
|
||||
}
|
25
app/Classes/LDAP/Attribute/Password/Argon2i.php
Normal file
25
app/Classes/LDAP/Attribute/Password/Argon2i.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class Argon2i extends Base
|
||||
{
|
||||
public const key = 'ARGON2';
|
||||
protected const subkey = 'i';
|
||||
protected const identifier = '$argon2i';
|
||||
|
||||
public static function subid(string $password): bool
|
||||
{
|
||||
return str_starts_with(base64_decode(self::password($password)),self::identifier.'$');
|
||||
}
|
||||
|
||||
public function compare(string $source,string $compare): bool
|
||||
{
|
||||
return password_verify($compare,base64_decode($this->password($source)));
|
||||
}
|
||||
|
||||
public function encode(string $password): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,base64_encode(password_hash($password,PASSWORD_ARGON2I)));
|
||||
}
|
||||
}
|
25
app/Classes/LDAP/Attribute/Password/Argon2id.php
Normal file
25
app/Classes/LDAP/Attribute/Password/Argon2id.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class Argon2id extends Base
|
||||
{
|
||||
public const key = 'ARGON2';
|
||||
protected const subkey = 'id';
|
||||
protected const identifier = '$argon2id';
|
||||
|
||||
public static function subid(string $password): bool
|
||||
{
|
||||
return str_starts_with(base64_decode(self::password($password)),self::identifier.'$');
|
||||
}
|
||||
|
||||
public function compare(string $source,string $compare): bool
|
||||
{
|
||||
return password_verify($compare,base64_decode($this->password($source)));
|
||||
}
|
||||
|
||||
public function encode(string $password): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,base64_encode(password_hash($password,PASSWORD_ARGON2ID)));
|
||||
}
|
||||
}
|
@@ -4,11 +4,65 @@ namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
abstract class Base
|
||||
{
|
||||
abstract public function compare(string $source,string $compare): bool;
|
||||
protected const subkey = '';
|
||||
|
||||
abstract public function encode(string $password): string;
|
||||
|
||||
public static function id(): string
|
||||
{
|
||||
return static::key.(static::subkey ? ':'.static::subkey : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the hash {TEXT}xxxx from the password
|
||||
*
|
||||
* @param string $password
|
||||
* @return string
|
||||
*/
|
||||
protected static function password(string $password): string
|
||||
{
|
||||
return preg_replace('/^{'.static::key.'}/','',$password);
|
||||
}
|
||||
|
||||
public static function shortid(): string
|
||||
{
|
||||
return static::key;
|
||||
}
|
||||
|
||||
/**
|
||||
* When multiple passwords share the same ID, this determines which hash is responsible for the presented password
|
||||
*
|
||||
* @param string $password
|
||||
* @return bool
|
||||
*/
|
||||
public static function subid(string $password): bool
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare our password to see if it is the same as that stored
|
||||
*
|
||||
* @param string $source Encoded source password
|
||||
* @param string $compare Password entered by user
|
||||
* @return bool
|
||||
*/
|
||||
public function compare(string $source,string $compare): bool
|
||||
{
|
||||
return $source === $this->encode($compare);
|
||||
}
|
||||
|
||||
protected function salted_hash(string $password,string $algo,int $salt_size=8,string $salt=NULL): string
|
||||
{
|
||||
if (is_null($salt))
|
||||
$salt = hex2bin(random_salt($salt_size));
|
||||
|
||||
return base64_encode(hash($algo,$password.$salt,true).$salt);
|
||||
}
|
||||
|
||||
protected function salted_salt(string $source): string
|
||||
{
|
||||
$hash = base64_decode(substr($source,strlen(static::key)+2));
|
||||
return substr($hash,strlen($hash)-static::salt/2);
|
||||
}
|
||||
}
|
22
app/Classes/LDAP/Attribute/Password/Bcrypt.php
Normal file
22
app/Classes/LDAP/Attribute/Password/Bcrypt.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class Bcrypt extends Base
|
||||
{
|
||||
public const key = 'BCRYPT';
|
||||
|
||||
private const options = [
|
||||
'cost' => 8,
|
||||
];
|
||||
|
||||
public function compare(string $source,string $compare): bool
|
||||
{
|
||||
return password_verify($compare,base64_decode($this->password($source)));
|
||||
}
|
||||
|
||||
public function encode(string $password): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,base64_encode(password_hash($password,PASSWORD_BCRYPT,self::options)));
|
||||
}
|
||||
}
|
@@ -4,12 +4,7 @@ namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class Clear extends Base
|
||||
{
|
||||
public const key = 'Clear';
|
||||
|
||||
public function compare(string $source,string $compare): bool
|
||||
{
|
||||
return $source === $compare;
|
||||
}
|
||||
public const key = '*clear*';
|
||||
|
||||
public function encode(string $password): string
|
||||
{
|
||||
|
13
app/Classes/LDAP/Attribute/Password/MD5.php
Normal file
13
app/Classes/LDAP/Attribute/Password/MD5.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class MD5 extends Base
|
||||
{
|
||||
public const key = 'MD5';
|
||||
|
||||
public function encode(string $password): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,base64_encode(hash('md5',$password,true)));
|
||||
}
|
||||
}
|
13
app/Classes/LDAP/Attribute/Password/SHA.php
Normal file
13
app/Classes/LDAP/Attribute/Password/SHA.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class SHA extends Base
|
||||
{
|
||||
public const key = 'SHA';
|
||||
|
||||
public function encode(string $password): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,base64_encode(hash('sha1',$password,true)));
|
||||
}
|
||||
}
|
13
app/Classes/LDAP/Attribute/Password/SHA256.php
Normal file
13
app/Classes/LDAP/Attribute/Password/SHA256.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class SHA256 extends Base
|
||||
{
|
||||
public const key = 'SHA256';
|
||||
|
||||
public function encode(string $password): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,base64_encode(hash('sha256',$password,true)));
|
||||
}
|
||||
}
|
13
app/Classes/LDAP/Attribute/Password/SHA384.php
Normal file
13
app/Classes/LDAP/Attribute/Password/SHA384.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class SHA384 extends Base
|
||||
{
|
||||
public const key = 'SHA384';
|
||||
|
||||
public function encode(string $password): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,base64_encode(hash('sha384',$password,true)));
|
||||
}
|
||||
}
|
13
app/Classes/LDAP/Attribute/Password/SHA512.php
Normal file
13
app/Classes/LDAP/Attribute/Password/SHA512.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class SHA512 extends Base
|
||||
{
|
||||
public const key = 'SHA512';
|
||||
|
||||
public function encode(string $password): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,base64_encode(hash('sha512',$password,true)));
|
||||
}
|
||||
}
|
22
app/Classes/LDAP/Attribute/Password/SMD5.php
Normal file
22
app/Classes/LDAP/Attribute/Password/SMD5.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class SMD5 extends Base
|
||||
{
|
||||
public const key = 'SMD5';
|
||||
protected const salt = 8;
|
||||
|
||||
public function compare(string $source,string $compare): bool
|
||||
{
|
||||
return $source === $this->encode($compare,$this->salted_salt($source));
|
||||
}
|
||||
|
||||
public function encode(string $password,string $salt=NULL): string
|
||||
{
|
||||
if (is_null($salt))
|
||||
$salt = hex2bin(random_salt(self::salt));
|
||||
|
||||
return sprintf('{%s}%s',self::key,$this->salted_hash($password,'md5',self::salt,$salt));
|
||||
}
|
||||
}
|
19
app/Classes/LDAP/Attribute/Password/SSHA.php
Normal file
19
app/Classes/LDAP/Attribute/Password/SSHA.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class SSHA extends Base
|
||||
{
|
||||
public const key = 'SSHA';
|
||||
protected const salt = 8;
|
||||
|
||||
public function compare(string $source,string $compare): bool
|
||||
{
|
||||
return $source === $this->encode($compare,$this->salted_salt($source));
|
||||
}
|
||||
|
||||
public function encode(string $password,string $salt=NULL): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,$this->salted_hash($password,'sha1',self::salt,$salt));
|
||||
}
|
||||
}
|
19
app/Classes/LDAP/Attribute/Password/SSHA256.php
Normal file
19
app/Classes/LDAP/Attribute/Password/SSHA256.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class SSHA256 extends Base
|
||||
{
|
||||
public const key = 'SSHA256';
|
||||
protected const salt = 8;
|
||||
|
||||
public function compare(string $source,string $compare): bool
|
||||
{
|
||||
return $source === $this->encode($compare,$this->salted_salt($source));
|
||||
}
|
||||
|
||||
public function encode(string $password,string $salt=NULL): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,$this->salted_hash($password,'sha256',self::salt,$salt));
|
||||
}
|
||||
}
|
19
app/Classes/LDAP/Attribute/Password/SSHA384.php
Normal file
19
app/Classes/LDAP/Attribute/Password/SSHA384.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class SSHA384 extends Base
|
||||
{
|
||||
public const key = 'SSHA384';
|
||||
protected const salt = 8;
|
||||
|
||||
public function compare(string $source,string $compare): bool
|
||||
{
|
||||
return $source === $this->encode($compare,$this->salted_salt($source));
|
||||
}
|
||||
|
||||
public function encode(string $password,string $salt=NULL): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,$this->salted_hash($password,'sha384',self::salt,$salt));
|
||||
}
|
||||
}
|
19
app/Classes/LDAP/Attribute/Password/SSHA512.php
Normal file
19
app/Classes/LDAP/Attribute/Password/SSHA512.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute\Password;
|
||||
|
||||
final class SSHA512 extends Base
|
||||
{
|
||||
public const key = 'SSHA512';
|
||||
protected const salt = 8;
|
||||
|
||||
public function compare(string $source,string $compare): bool
|
||||
{
|
||||
return $source === $this->encode($compare,$this->salted_salt($source));
|
||||
}
|
||||
|
||||
public function encode(string $password,string $salt=NULL): string
|
||||
{
|
||||
return sprintf('{%s}%s',self::key,$this->salted_hash($password,'sha512',self::salt,$salt));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user