Support Initialisation vector in crypt/decrypt

This commit is contained in:
Laurent Destailleur 2022-08-25 02:04:48 +02:00
parent 17c404e940
commit a7f9ec159b

View File

@ -91,6 +91,21 @@ function dol_decode($chain, $key = '1')
return $chain;
}
/**
* Return a string of random bytes (hexa string) with length = $length fro cryptographic purposes.
*
* @param int $length Length of random string
* @return string Random string
*/
function dolGetRandomBytes($length)
{
if (function_exists('random_bytes')) { // Available with PHP 7 only.
return bin2hex(random_bytes((int) floor($length / 2))); // the bin2hex will double the number of bytes so we take length / 2
}
return bin2hex(openssl_random_pseudo_bytes((int) floor($length / 2))); // the bin2hex will double the number of bytes so we take length / 2. May be very slow on Windows.
}
/**
* Encode a string with a symetric encryption. Used to encrypt sensitive data into database.
* Note: If a backup is restored onto another instance with a different $dolibarr_main_instance_unique_id, then decoded value will differ.
@ -121,17 +136,20 @@ function dolEncrypt($chain, $key = '', $ciphering = "AES-256-CTR")
$newchain = $chain;
if (!function_exists('openssl_encrypt')) {
return $chain;
} else {
$ivlen = openssl_cipher_iv_length($ciphering);
if ($ivlen < 0 || $ivlen > 32) {
$ivlen = 32;
if (function_exists('openssl_encrypt')) {
$ivlen = 16;
if (function_exists('openssl_cipher_iv_length')) {
$ivlen = openssl_cipher_iv_length($ciphering);
}
$ivseed = mt_rand(0, pow(2, $ivlen) - 1);
if ($ivlen === false || $ivlen < 1 || $ivlen > 32) {
$ivlen = 16;
}
$ivseed = dolGetRandomBytes($ivlen);
$newchain = openssl_encrypt($chain, $ciphering, $key, null, $ivseed);
return 'dolcrypt:'.$ciphering.':'.$ivseed.':'.$newchain;
} else {
return $chain;
}
}
@ -161,7 +179,7 @@ function dolDecrypt($chain, $key = '')
$ciphering = $reg[1];
if (function_exists('openssl_decrypt')) {
$tmpexplode = explode(':', $reg[2]);
if (!empty($tmpexplode[1]) && is_numeric($tmpexplode[0])) {
if (!empty($tmpexplode[1]) && is_string($tmpexplode[0])) {
$newchain = openssl_decrypt($tmpexplode[1], $ciphering, $key, null, $tmpexplode[0]);
} else {
$newchain = openssl_decrypt($tmpexplode[0], $ciphering, $key, null, null);