<?php
/**
* @class crypt
* @brief Functions to handle passwords or sensitive data
*
* @package Clearbricks
* @subpackage Common
*
* @copyright Olivier Meunier & Association Dotclear
* @copyright GPL-2.0-only
*/
class crypt
{
/**
* SHA1 or MD5 + HMAC
*
* Returns an HMAC encoded value of <var>$data</var>, using the said <var>$key</var>
* and <var>$hashfunc</var> as hash method (sha1 or md5 are accepted if hash_hmac function not exists.)
*
* @param string $key Hash key
* @param string $data Data
* @param string $hashfunc Hash function (md5 or sha1)
* @return string
*/
public static function hmac(string $key, string $data, string $hashfunc = 'sha1'): string
{
if (function_exists('hash_hmac')) {
if (!in_array($hashfunc, hash_algos())) {
$hashfunc = 'sha1';
}
return hash_hmac($hashfunc, $data, $key);
}
return self::hmac_legacy($key, $data, $hashfunc);
}
public static function hmac_legacy(string $key, string $data, string $hashfunc = 'sha1'): string
{
// Legacy way
if ($hashfunc != 'sha1') {
$hashfunc = 'md5';
}
$blocksize = 64;
if (strlen($key) > $blocksize) {
$key = pack('H*', $hashfunc($key));
}
$key = str_pad($key, $blocksize, chr(0x00));
$ipad = str_repeat(chr(0x36), $blocksize);
$opad = str_repeat(chr(0x5c), $blocksize);
$hmac = pack('H*', $hashfunc(($key ^ $opad) . pack('H*', $hashfunc(($key ^ $ipad) . $data))));
return bin2hex($hmac);
}
/**
* Password generator
*
* Returns an n characters random password.
*
* @param integer $length required length
* @return string
*/
public static function createPassword(int $length = 8): string
{
$pwd = [];
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
$chars2 = '$!@';
for ($i = 0; $i < $length; $i++) {
$pwd[] = $chars[rand(0, strlen($chars) - 1)];
}
for ($j = 0; $j < (int) ($length / 4); $j++) {
$pos = rand(0, 3) + 4 * $j;
$pwd[$pos] = $chars2[rand(0, strlen($chars2) - 1)];
}
return implode('', $pwd);
}
}