3v4l.org

run code in 300+ PHP versions simultaneously
<?php if (PHP_VERSION_ID < 70000) { die('no'); } /** * Use HKDF to derive multiple keys from one. * http://tools.ietf.org/html/rfc5869 * * @param string $hash Hash Function * @param string $ikm Initial Keying Material * @param int $length How many bytes? * @param string $info What sort of key are we deriving? * @param string $salt * @return string * @throws Exception */ function hash_hkdf(string $algo, string $ikm, int $length, string $info = '', $salt = null) { $digest_length = mb_strlen(hash_hmac($algo, '', '', true), '8bit'); // Sanity-check the desired output length. if (empty($length) || !is_int($length) || $length < 0 || $length > 255 * $digest_length) { throw new Exception("Bad output length requested of HKDF."); } // "if [salt] not provided, is set to a string of HashLen zeroes." if ($salt === null) { $salt = str_repeat("\x00", $digest_length); } // HKDF-Extract: // PRK = HMAC-Hash(salt, IKM) // The salt is the HMAC key. $prk = hash_hmac($algo, $ikm, $salt, true); // HKDF-Expand: // This check is useless, but it serves as a reminder to the spec. if (mb_strlen($prk, '8bit') < $digest_length) { throw new Exception('HKDF-Expand failed'); } // T(0) = '' $t = ''; $last_block = ''; for ($block_index = 1; mb_strlen($t, '8bit') < $length; ++$block_index) { // T(i) = HMAC-Hash(PRK, T(i-1) | info | 0x??) $last_block = hash_hmac( $algo, $last_block . $info . chr($block_index), $prk, true ); // T = T(1) | T(2) | T(3) | ... | T(N) $t .= $last_block; } // ORM = first L octets of T $orm = mb_substr($t, 0, $length, '8bit'); if ($orm === false) { throw new Exception('Unexpected error'); } return $orm; } /** * Encrypt a message with AES-256-CTR + HMAC-SHA256 * @param string $message * @param string $key * @return string */ function aes256ctr_hmacsha256_encrypt(string $message, string $key) { $iv = random_bytes(16); $salt = random_bytes(16); $eKey = hash_hkdf('sha256', $key, 32, 'Encryption Key', $salt); $aKey = hash_hkdf('sha256', $key, 32, 'Authentication Key', $salt); $ciphertext = $iv . $salt . openssl_encrypt( $message, 'aes-256-ctr', $eKey, OPENSSL_RAW_DATA, $iv ); $mac = hash_hmac('sha256', $ciphertext, $aKey, true); return base64_encode($mac . $ciphertext); } /** * Decrypt a message with AES-256-CTR + HMAC-SHA256 * @param string $message * @param string $key * @return string * @throws Exception */ function aes256ctr_hmacsha256_decrypt(string $ciphertext, string $key) { $decode = base64_decode($ciphertext); if ($decode === false) { throw new Exception("Encoding error"); } $mac = mb_substr($decode, 0, 32, '8bit'); $iv = mb_substr($decode, 32, 16, '8bit'); $salt = mb_substr($decode, 48, 16, '8bit'); $ciphertext = mb_substr($decode, 64, null, '8bit'); $aKey = hash_hkdf('sha256', $key, 32, 'Authentication Key', $salt); $calcMac = hash_hmac('sha256', $iv . $salt . $ciphertext, $aKey, true); if (!hash_equals($calcMac, $mac)) { throw new Exception("Invalid message"); } $eKey = hash_hkdf('sha256', $key, 32, 'Encryption Key', $salt); return openssl_decrypt( $ciphertext, 'aes-256-ctr', $eKey, OPENSSL_RAW_DATA, $iv ); } $key = random_bytes(32); $message = "This code rocks"; $ciphertext = aes256ctr_hmacsha256_encrypt($message, $key); var_dump($ciphertext); $plaintext = aes256ctr_hmacsha256_decrypt($ciphertext, $key); var_dump($plaintext);
Output for 7.4.0
Fatal error: Cannot redeclare hash_hkdf() in /in/5Nebh on line 18
Process exited with code 255.
Output for 7.1.5 - 7.1.33, 7.2.17 - 7.2.25, 7.3.0 - 7.3.12
Fatal error: Cannot redeclare hash_hkdf() in /in/5Nebh on line 59
Process exited with code 255.
Output for 7.1.0
string(108) "zggLjMpdLcjp7Sjc04q0XNU6UpAwHYT25IcidWqdnK9Iis67sYJdtFxU+cm3DSJ0dc38vxl+1Uere17cvvOGXa18WeePSTV1opk4opPILA==" string(15) "This code rocks"
Output for 7.0.20
string(108) "z4Cn7tGilfi73cetI95+XtOwF9xjXx0ETyz7yEplCkxLdI8zuRl9GkLYsiwLFpt7CpQ+RnzqKVFISgQtUsethhzfdBGwm1ob4rAk5H2SHg==" string(15) "This code rocks"
Output for 7.0.10
string(108) "bKowJSv5tLYCDwj5oB0B3WtOA/RzmtSGZgXJhthpdMsmUeNKAdpS+4K/IcyoHSgt7IbZz2nbcUbir0JBKFdo/GZ3zmVxyhqxJdTSU6K/9g==" string(15) "This code rocks"
Output for 7.0.9
string(108) "Z/8hXQvqHsDec21F5If90RGCZM0YUslYLlIe++V0iZm1HNeaE8i7nWRexXfCAVMyPDalNO9qt+TbQatMIJfOEs4WRrC8k5JOMk98+Vfl3A==" string(15) "This code rocks"
Output for 7.0.8
string(108) "pUDsC+n3lA1W5djt/vhYHkNXj6TrTOZNqnH/EJLKAE9jQ1dEo27eFbaq5VkUfOfS8/+OXiIjSCqPWkAuahblcvt+9GofiqDDjE9EVhQCsQ==" string(15) "This code rocks"
Output for 7.0.7
string(108) "Q3aNDDVsqQiWZrWLn5qZKvMJsqmxd2b5BsnkRosJbmYpAlpBcXP+m3ixSW9WiFCQUNBdLBrYAtTBdUHZBGxsgOPITVBXawnpJLvMpGfl8w==" string(15) "This code rocks"
Output for 7.0.6
string(108) "tBeo1pPegcsrC2DQyJGnxmtOUj22tXV+ch+yD01FueJPKY+AKYxm0x90N1XrALVrSvCM52An2gKmtF+i0DVsk0/JbYbENPAIJlFtHRoi2w==" string(15) "This code rocks"
Output for 7.0.5
string(108) "p4RljddC/1XbMx+t6JsAePprEW5jXhGQeePNRO0I0cRiz7e0LgqDP8m1OCmnQxICfJdMMwh/aGEHIBM0nmdSi0oUY7ALGEUR+GglzRJl6A==" string(15) "This code rocks"
Output for 7.0.4
string(108) "myWKQENiacpd+l/3hjc09iSvQUm7DIm4e5GsWnzsI91HZutha2J2ysaPIPJioUGFu4Erh/3oVbS4zf6pVdk92jm6Rvsf+JhoqIni0XC11A==" string(15) "This code rocks"
Output for 7.0.3
string(108) "Mq8tqnz+ns4y20QvcmhFPMP3pugYiXFZNNm0nHhp40/2TNGv7d77EHHwyZm7ohg46FqTtNjpQV09OwVkhrz157YahmgA1TlJAQZkuTWDRg==" string(15) "This code rocks"
Output for 7.0.2
string(108) "jZhRpuxMlZi9Btt7cETz3FEDcVK8vrJ6DsdWfc/X8JPL0rLfrciEMew/66Zm/j5th+N6e7QztAcrG9jYCio0RVyDmxLX1z2DcUm+i38A1Q==" string(15) "This code rocks"
Output for 7.0.1
string(108) "QSHCQel8l4vdqI0+E/FHS1iJFy8XXnVJmJ/QQJcCHny7n940WrP50nwS6X31oaasnynVpd/HVJhvCoCWtJnSBf8wQVHU2+owtcVFtE1JOg==" string(15) "This code rocks"
Output for 7.0.0
string(108) "RAyL3f3TaX8cJarwuXoAQ1HFaDEOIiBc7e/3ktleJ7Lk37YMkczJKVWYwy5mD7is1+QH7OsHPhELHSFixqXuDqpL4nZ1r06qJa+SkYXVKQ==" string(15) "This code rocks"
Output for 5.5.0 - 5.5.38, 5.6.0 - 5.6.28
Fatal error: Default value for parameters with a class type hint can only be NULL in /in/5Nebh on line 18
Process exited with code 255.

preferences:
49.2 ms | 427 KiB | 5 Q