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 $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. * 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. * 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; $newchain = $chain;
if (!function_exists('openssl_encrypt')) { if (function_exists('openssl_encrypt')) {
return $chain; $ivlen = 16;
} else { if (function_exists('openssl_cipher_iv_length')) {
$ivlen = openssl_cipher_iv_length($ciphering); $ivlen = openssl_cipher_iv_length($ciphering);
if ($ivlen < 0 || $ivlen > 32) {
$ivlen = 32;
} }
$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); $newchain = openssl_encrypt($chain, $ciphering, $key, null, $ivseed);
return 'dolcrypt:'.$ciphering.':'.$ivseed.':'.$newchain; return 'dolcrypt:'.$ciphering.':'.$ivseed.':'.$newchain;
} else {
return $chain;
} }
} }
@ -161,7 +179,7 @@ function dolDecrypt($chain, $key = '')
$ciphering = $reg[1]; $ciphering = $reg[1];
if (function_exists('openssl_decrypt')) { if (function_exists('openssl_decrypt')) {
$tmpexplode = explode(':', $reg[2]); $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]); $newchain = openssl_decrypt($tmpexplode[1], $ciphering, $key, null, $tmpexplode[0]);
} else { } else {
$newchain = openssl_decrypt($tmpexplode[0], $ciphering, $key, null, null); $newchain = openssl_decrypt($tmpexplode[0], $ciphering, $key, null, null);