From a7f9ec159b19a7ef5f889e0a212a294a7b02c827 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 25 Aug 2022 02:04:48 +0200 Subject: [PATCH] Support Initialisation vector in crypt/decrypt --- htdocs/core/lib/security.lib.php | 34 ++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 62c0a22e76b..bc0dd522d1b 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -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);