3v4l.org

run code in 300+ PHP versions simultaneously
<?php if (PHP_VERSION_ID < 70000) exit; $res = openssl_pkey_new([ 'digest_alg' => 'sha256', 'private_key_bite' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA ]); openssl_pkey_export($res, $privateKey); $publicKey = openssl_pkey_get_details($res)['key']; $message = 'Prime Numbers Rock!'; $aesKey = random_bytes(32); // Basically a poor-man's HKDF by just using HMAC $keyE = hash_hmac('sha256', 'Encryption Key', $aesKey, true); $keyA = hash_hmac('sha256', 'Authentication Key', $aesKey, true); $iv = random_bytes(16); $ciphertext = openssl_encrypt($message, 'aes-256-ctr', $keyE, OPENSSL_RAW_DATA, $iv); $mac = hash_hmac('sha256', $iv .$ciphertext, $keyA, true); $combined = $mac . $iv . $ciphertext; $rsaCipher = ''; openssl_public_encrypt($aesKey, $rsaCipher, $publicKey, OPENSSL_PKCS1_OAEP_PADDING); $sendMe = $rsaCipher . $combined; var_dump(base64_encode($sendMe)); ## DECRYPTION ## $rsaPart = mb_substr($sendMe, 0, 256, '8bit'); // Assuming 2048-bit RSA $aesPart = mb_substr($sendMe, 256, null, '8bit'); $mac = mb_substr($aesPart, 0, 32, '8bit'); $iv = mb_substr($aesPart, 32, 16, '8bit'); $cipher = mb_substr($aesPart, 48, null, '8bit'); $aesKey = ''; openssl_private_decrypt($rsaPart, $aesKey, $privateKey, OPENSSL_PKCS1_OAEP_PADDING); $keyE = hash_hmac('sha256', 'Encryption Key', $aesKey, true); $keyA = hash_hmac('sha256', 'Authentication Key', $aesKey, true); $calc = hash_hmac('sha256', $iv . $cipher, $keyA, true); if (!hash_equals($calc, $mac)) { throw new Exception('MAC validation failure'); } $decrypted = openssl_decrypt($cipher, 'aes-256-ctr', $keyE, OPENSSL_RAW_DATA, $iv); var_dump($decrypted); // string(19) "Prime Numbers Rock!"

preferences:
28.83 ms | 409 KiB | 5 Q