3v4l.org

run code in 300+ PHP versions simultaneously
<?php const CIPHER = MCRYPT_RIJNDAEL_128; const KEY_BYTE_SIZE = 16; const CIPHER_MODE = 'cbc'; const HASH_FUNCTION = 'sha256'; const MAC_BYTE_SIZE = 32; const ENCRYPTION_INFO = 'PIPS|KeyForEncryption'; const AUTHENTICATION_INFO = 'PIPS|KeyForAuthentication'; $key = base64_decode('wdmd3XIhnOAelom4Y8yPbw=='); $result = Encrypt('asdfasdfasdfasdf', $key); print urlsafe_b64encode($result); $ekey = HKDF(HASH_FUNCTION, $key, KEY_BYTE_SIZE, ENCRYPTION_INFO); //print "$ekey\n"; //print urlsafe_b64encode($ekey) . "\n"; //$ivsize = mcrypt_get_iv_size(CIPHER, CIPHER_MODE); //if ($ivsize === FALSE || $ivsize <= 0) { // throw new CannotPerformOperationException(); //} $ivsize= 16; $iv = SecureRandom($ivsize); //print urlsafe_b64encode($iv) . "\n"; $raw = PlainEncrypt('asdfasdfasdfasdf', $ekey, $iv); //print $raw . "\n"; //print urlsafe_b64encode($raw); function urlsafe_b64encode($string) { $data = base64_encode($string); $data = str_replace(array('+','/','='),array('-','_',''),$data); return $data; } function urlsafe_b64decode($string) { $data = str_replace(array('-','_'),array('+','/'),$string); return base64_decode($data); } function HKDF($hash, $ikm, $length, $info = '', $salt = NULL) { // Find the correct digest length as quickly as we can. $digest_length = MAC_BYTE_SIZE; if ($hash != HASH_FUNCTION) { $digest_length = strlen(hash_hmac($hash, '', '', true)); } // Sanity-check the desired output length. if (empty($length) || !is_int($length) || $length < 0 || $length > 255 * $digest_length) { return CannotPerformOperationException(); } // "if [salt] not provided, is set to a string of HashLen zeroes." if (is_null($salt)) { $salt = str_repeat("\x00", $digest_length); } // HKDF-Extract: // PRK = HMAC-Hash(salt, IKM) // The salt is the HMAC key. $prk = hash_hmac($hash, $ikm, $salt, true); // HKDF-Expand: // This check is useless, but it serves as a reminder to the spec. if (strlen($prk) < $digest_length) { throw new CannotPerformOperationException(); } // T(0) = '' $t = ''; $last_block = ''; for ($block_index = 1; strlen($t) < $length; $block_index++) { // T(i) = HMAC-Hash(PRK, T(i-1) | info | 0x??) $last_block = hash_hmac( $hash, $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 = substr($t, 0, $length); if ($orm === FALSE) { throw new CannotPerformOperationException(); } return $orm; } function SecureRandom($octets) { return urlsafe_b64decode('FSDTs5UoRN07CAeB84KVIw'); $random = mcrypt_create_iv($octets, MCRYPT_DEV_URANDOM); if ($random === FALSE) { throw new CannotPerformOperationException(); } else { return $random; } } function PlainEncrypt($plaintext, $key, $iv) { $crypt = mcrypt_module_open(CIPHER, "", CIPHER_MODE, ""); if ($crypt === FALSE) { throw new CannotPerformOperationException(); } // Pad the plaintext to a multiple of the block size. $block = mcrypt_enc_get_block_size($crypt); $pad = $block - (strlen($plaintext) % $block); $plaintext .= str_repeat(chr($pad), $pad); $ret = mcrypt_generic_init($crypt, $key, $iv); if ($ret !== 0) { throw new CannotPerformOperationException(); } $ciphertext = mcrypt_generic($crypt, $plaintext); $ret = mcrypt_generic_deinit($crypt); if ($ret !== TRUE) { throw new CannotPerformOperationException(); } $ret = mcrypt_module_close($crypt); if ($ret !== TRUE) { throw new CannotPerformOperationException(); } return $ciphertext; } function Encrypt($plaintext, $key) { if (strlen($key) !== KEY_BYTE_SIZE) { throw new CannotPerformOperationException("Bad key."); } // Generate a sub-key for encryption. $keysize = KEY_BYTE_SIZE; $ekey = HKDF(HASH_FUNCTION, $key, $keysize, ENCRYPTION_INFO); // Generate a random initialization vector. $ivsize = mcrypt_get_iv_size(CIPHER, CIPHER_MODE); if ($ivsize === FALSE || $ivsize <= 0) { throw new CannotPerformOperationException(); } $iv = SecureRandom($ivsize); $ciphertext = $iv . PlainEncrypt($plaintext, $ekey, $iv); // Generate a sub-key for authentication and apply the HMAC. $akey = HKDF(HASH_FUNCTION, $key, KEY_BYTE_SIZE, AUTHENTICATION_INFO); $auth = hash_hmac(HASH_FUNCTION, $ciphertext, $akey, true); $ciphertext = $auth . $ciphertext; return $ciphertext; } ?>

preferences:
40.6 ms | 402 KiB | 5 Q