3v4l.org

run code in 300+ PHP versions simultaneously
<?php /** * http://stackoverflow.com/questions/9262109/php-simplest-two-way-encryption/30189841#30189841 * * This is not safe to use */ class UnsafeCrypto { const METHOD = 'aes-256-ctr'; /** * Encrypts (but does not authenticate) a message * * @param string $message - plaintext message * @param string $key - encryption key (raw binary expected) * @param boolean $encode - set to TRUE to return a base64-encoded * @return string (raw binary) */ public static function encrypt($message, $key, $encode = false) { $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = openssl_random_pseudo_bytes($nonceSize); $ciphertext = openssl_encrypt( $message, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); // Now let's pack the IV and the ciphertext together // Naively, we can just concatenate if ($encode) { return base64_encode($nonce.$ciphertext); } return $nonce.$ciphertext; } /** * Decrypts (but does not verify) a message * * @param string $message - ciphertext message * @param string $key - encryption key (raw binary expected) * @param boolean $encoded - are we expecting an encoded string? * @return string */ public static function decrypt($message, $key, $encoded = false) { if ($encoded) { $message = base64_decode($message, true); if ($message === false) { throw new Exception('Encryption failure'); } } $nonceSize = openssl_cipher_iv_length(self::METHOD); $nonce = mb_substr($message, 0, $nonceSize, '8bit'); $ciphertext = mb_substr($message, $nonceSize, null, '8bit'); $plaintext = openssl_decrypt( $ciphertext, self::METHOD, $key, OPENSSL_RAW_DATA, $nonce ); return $plaintext; } } class SaferCrypto extends UnsafeCrypto { const HASH_ALGO = 'sha256'; /** * Encrypts then MACs a message * * @param string $message - plaintext message * @param string $key - encryption key (raw binary expected) * @param boolean $encode - set to TRUE to return a base64-encoded string * @return string (raw binary) */ public static function encrypt($message, $key, $encode = false) { list($encKey, $authKey) = self::splitKeys($key); // Pass to UnsafeCrypto::encrypt $ciphertext = parent::encrypt($message, $encKey); // Calculate a MAC of the IV and ciphertext $mac = hash_hmac(self::HASH_ALGO, $ciphertext, $authKey, true); if ($encode) { return base64_encode($mac.$ciphertext); } // Prepend MAC to the ciphertext and return to caller return $mac.$ciphertext; } /** * Decrypts a message (after verifying integrity) * * @param string $message - ciphertext message * @param string $key - encryption key (raw binary expected) * @param boolean $encoded - are we expecting an encoded string? * @return string (raw binary) */ public static function decrypt($message, $key, $encoded = false) { list($encKey, $authKey) = self::splitKeys($key); if ($encoded) { $message = base64_decode($message, true); if ($message === false) { throw new Exception('Encryption failure'); } } // Hash Size -- in case HASH_ALGO is changed $hs = mb_strlen(hash(self::HASH_ALGO, '', true), '8bit'); $mac = mb_substr($message, 0, $hs, '8bit'); $ciphertext = mb_substr($message, $hs, null, '8bit'); $calculated = hash_hmac( self::HASH_ALGO, $ciphertext, $authKey, true ); if (!self::hashEquals($mac, $calculated)) { throw new Exception('Encryption failure'); } // Pass to UnsafeCrypto::decrypt $plaintext = parent::decrypt($ciphertext, $encKey); return $plaintext; } /** * Splits a key into two separate keys; one for encryption * and the other for authenticaiton * * @param string $masterKey (raw binary) * @return array (two raw binary strings) */ protected static function splitKeys($masterKey) { // You really want to implement HKDF here instead! return [ hash_hmac(self::HASH_ALGO, 'ENCRYPTION', $masterKey, true), hash_hmac(self::HASH_ALGO, 'AUTHENTICATION', $masterKey, true) ]; } /** * Compare two strings without leaking timing information * * @param string $a * @param string $b * @return boolean */ protected static function hashEquals($a, $b) { if (function_exists('hash_equals')) { return hash_equals($a, $b); } $nonce = openssl_random_pseudo_bytes(32); return hash_hmac(self::HASH_ALGO, $a, $nonce) === hash_hmac(self::HASH_ALGO, $b, $nonce); } } $message = 'Ready your ammunition; we attack at dawn.'; $key = hex2bin('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f'); $encrypted = SaferCrypto::encrypt($message, $key); $decrypted = SaferCrypto::decrypt($encrypted, $key); var_dump($encrypted, $decrypted);

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.3.130.0070.00617.66
8.3.120.0110.00418.70
8.3.110.0090.00919.55
8.3.100.0100.00517.64
8.3.90.0130.00723.34
8.3.80.0120.00520.96
8.3.70.0140.00320.00
8.3.60.0160.00220.67
8.3.50.0210.00621.49
8.3.40.0140.00421.04
8.3.30.0100.00621.02
8.3.20.0120.00321.51
8.3.10.0070.00622.00
8.3.00.0100.00120.74
8.2.250.0160.00517.10
8.2.240.0180.00216.89
8.2.230.0110.00319.58
8.2.220.0110.00720.44
8.2.210.0120.00123.28
8.2.200.0150.00020.76
8.2.190.0120.00420.16
8.2.180.0080.00820.56
8.2.170.0130.00522.48
8.2.160.0100.00521.31
8.2.150.0080.00622.83
8.2.140.0080.00523.04
8.2.130.0120.00123.52
8.2.120.0080.00521.79
8.2.110.0100.00521.23
8.2.100.0100.00520.74
8.2.90.0100.00421.73
8.2.80.0070.00820.64
8.2.70.0070.00820.79
8.2.60.0090.00520.77
8.2.50.0090.00420.72
8.2.40.0050.00620.38
8.2.30.0080.00620.78
8.2.20.0050.00620.39
8.2.10.0080.00619.96
8.2.00.0090.00420.00
8.1.300.0100.00517.27
8.1.290.0070.00724.59
8.1.280.0120.00522.91
8.1.270.0090.00522.72
8.1.260.0080.00723.47
8.1.250.0110.00424.07
8.1.240.0130.00322.67
8.1.230.0100.00521.59
8.1.220.0120.00619.58
8.1.210.0090.00320.94
8.1.200.0090.00419.11
8.1.190.0080.00520.42
8.1.180.0060.00720.64
8.1.170.0110.00620.92
8.1.160.0060.00920.14
8.1.150.0100.00420.02
8.1.140.0080.00619.68
8.1.130.0100.00320.07
8.1.120.0090.00419.83
8.1.110.0100.00519.44
8.1.100.0100.00519.19
8.1.90.0140.00318.96
8.1.80.0090.00618.81
8.1.70.0100.00518.75
8.1.60.0100.00618.89
8.1.50.0130.00418.83
8.1.40.0100.00718.87
8.1.30.0120.00518.94
8.1.20.0090.00818.87
8.1.10.0130.00418.86
8.1.00.0140.00318.79
8.0.300.0120.00321.07
8.0.290.0120.00420.05
8.0.280.0130.00319.84
8.0.270.0110.00419.74
8.0.260.0120.00319.59
8.0.250.0110.00419.27
8.0.240.0110.00618.87
8.0.230.0100.00918.62
8.0.220.0140.00618.56
8.0.210.0150.00318.34
8.0.200.0110.00618.38
8.0.190.0120.00518.38
8.0.180.0130.00518.34
8.0.170.0130.00518.41
8.0.160.0120.00618.37
8.0.150.0110.00718.41
8.0.140.0100.00818.34
8.0.130.0130.00517.91
8.0.120.0130.00518.35
8.0.110.0130.00518.35
8.0.100.0120.00418.22
8.0.90.0120.00318.16
8.0.80.0110.00618.18
8.0.70.0120.00318.22
8.0.60.0090.00518.22
8.0.50.0100.00418.22
8.0.30.0110.00817.81
8.0.20.0120.00517.84
8.0.10.0130.00618.02
8.0.00.0090.00817.82
7.4.330.0140.00717.70
7.4.320.0130.00518.57
7.4.300.0120.00418.07
7.4.290.0110.00617.96
7.4.280.0120.00617.76
7.4.270.0120.00518.08
7.4.260.0100.00717.74
7.4.250.0140.00518.05
7.4.240.0150.00318.10
7.4.230.0110.00617.86
7.4.220.0120.00517.91
7.4.210.0120.00517.92
7.4.200.0100.00317.86
7.4.190.0110.00418.13
7.4.180.0080.00718.10
7.4.160.0090.00817.55
7.4.150.0080.00817.58
7.4.140.0090.00817.59
7.4.130.0090.00717.54
7.4.120.0090.00717.47
7.4.110.0090.00617.44
7.4.100.0090.00617.64
7.4.90.0100.00617.40
7.4.80.0120.00817.36
7.4.70.0100.00817.17
7.4.60.0120.00717.19
7.4.50.0110.00617.22
7.4.40.0110.00717.23
7.4.30.0090.00817.22
7.4.20.0080.00917.20
7.4.10.0090.00817.04
7.4.00.0100.00716.85
7.3.330.0150.00317.79
7.3.320.0110.00717.62
7.3.310.0120.00517.98
7.3.300.0110.00517.82
7.3.290.0130.00217.78
7.3.280.0090.00617.51
7.3.270.0110.00517.47
7.3.260.0100.00617.40
7.3.250.0090.00817.27
7.3.240.0100.00617.41
7.3.230.0090.00717.37
7.3.220.0090.00717.33
7.3.210.0100.00717.16
7.3.200.0120.00717.11
7.3.190.0120.00717.08
7.3.180.0100.00917.07
7.3.170.0120.00817.09
7.3.160.0140.00617.08
7.3.150.0110.00717.03
7.3.140.0110.00817.03
7.3.130.0110.00616.82
7.3.120.0110.00816.76
7.3.110.0100.00816.71
7.3.100.0100.00816.52
7.3.90.0100.00916.62
7.3.80.0100.00816.50
7.3.70.0100.00716.49
7.3.60.0100.00716.52
7.3.50.0100.00716.54
7.3.40.0110.00616.45
7.3.30.0100.00916.48
7.3.20.0100.00917.08
7.3.10.0150.00716.99
7.3.00.0160.00816.89
7.2.340.0140.00817.40
7.2.330.0130.00817.24
7.2.320.0130.00917.20
7.2.310.0120.00917.11
7.2.300.0150.00717.11
7.2.290.0120.00817.12
7.2.280.0110.00917.12
7.2.270.0120.00917.07
7.2.260.0130.00716.89
7.2.250.0100.00916.84
7.2.240.0110.00916.80
7.2.230.0110.00916.59
7.2.220.0120.00816.62
7.2.210.0110.00816.59
7.2.200.0120.00816.71
7.2.190.0120.00816.65
7.2.180.0110.00916.65
7.2.170.0120.00916.63
7.2.160.0130.00716.71
7.2.150.0130.00817.30
7.2.140.0130.00917.31
7.2.130.0160.00717.30
7.2.120.0130.00917.19
7.2.110.0140.00917.23
7.2.100.0130.01017.20
7.2.90.0140.00817.17
7.2.80.0140.00817.20
7.2.70.0140.00817.19
7.2.60.0130.00917.17
7.2.50.0140.00717.23
7.2.40.0150.00817.21
7.2.30.0140.00817.24
7.2.20.0140.00817.21
7.2.10.0130.00917.21
7.2.00.0150.00917.17
7.1.330.0150.00716.57
7.1.320.0130.00816.36
7.1.310.0130.00716.29
7.1.300.0140.00716.30
7.1.290.0130.00716.31
7.1.280.0160.00816.18
7.1.270.0150.00716.27
7.1.260.0120.00716.23
7.1.250.0140.00816.11
7.1.240.0160.00816.07
7.1.230.0150.00816.12
7.1.220.0150.00816.13
7.1.210.0140.00816.10
7.1.200.0160.00616.10
7.1.190.0140.00816.12
7.1.180.0140.00716.06
7.1.170.0160.00616.11
7.1.160.0150.00816.11
7.1.150.0160.00816.06
7.1.140.0140.00816.09
7.1.130.0160.00716.08
7.1.120.0170.00816.09
7.1.110.0150.00716.09
7.1.100.0160.00816.08
7.1.90.0150.00716.10
7.1.80.0160.00716.17
7.1.70.0160.00816.03
7.1.60.0150.00716.13
7.1.50.0160.00816.18
7.1.40.0160.00616.17
7.1.30.0150.00716.21
7.1.20.0130.00816.18
7.1.10.0160.00716.16
7.1.00.0150.00716.13
7.0.330.0190.00815.85
7.0.320.0150.00915.86
7.0.310.0180.00715.83
7.0.300.0180.00615.86
7.0.290.0210.00615.84
7.0.280.0160.00715.86
7.0.270.0170.00715.86
7.0.260.0210.00715.83
7.0.250.0150.00815.90
7.0.240.0170.00716.02
7.0.230.0170.00715.98
7.0.220.0170.00715.81
7.0.210.0160.00815.98
7.0.200.0150.00815.95
7.0.190.0160.00715.98
7.0.180.0160.00815.93
7.0.170.0170.00816.02
7.0.160.0140.00815.97
7.0.150.0160.00715.96
7.0.140.0160.00815.99
7.0.130.0150.00715.96
7.0.120.0170.00615.95
7.0.110.0160.00915.99
7.0.100.0180.00715.88
7.0.90.0170.00615.93
7.0.80.0170.00615.86
7.0.70.0160.00715.93
7.0.60.0140.00815.89
7.0.50.0140.00715.87
7.0.40.0150.00715.88
7.0.30.0140.00715.90
7.0.20.0140.00815.88
7.0.10.0160.00815.92
7.0.00.0140.00715.85
5.6.400.0130.00816.17
5.6.390.0130.00816.15
5.6.380.0130.00916.01
5.6.370.0130.00916.05
5.6.360.0140.00716.10
5.6.350.0130.00916.05
5.6.340.0140.00816.04
5.6.330.0150.00816.10
5.6.320.0140.00816.04
5.6.310.0140.00816.01
5.6.300.0130.00816.09
5.6.290.0130.00816.05
5.6.280.0130.00816.06
5.6.270.0120.00816.06
5.6.260.0120.00716.05
5.6.250.0130.00816.03
5.6.240.0130.00816.10
5.6.230.0120.00816.05
5.6.220.0130.00716.07
5.6.210.0130.00716.07
5.6.200.0130.00816.10
5.6.190.0110.00816.07
5.6.180.0130.00816.11
5.6.170.0120.00916.13
5.6.160.0130.00816.15
5.6.150.0120.00916.10
5.6.140.0120.00816.06
5.6.130.0140.00716.06
5.6.120.0110.01016.05
5.6.110.0130.00815.99
5.6.100.0130.00715.98
5.6.90.0120.00815.97
5.6.80.0110.01015.92
5.6.70.0120.00816.00
5.6.60.0120.00815.97
5.6.50.0130.00815.95
5.6.40.0120.00815.94
5.6.30.0140.00815.92
5.6.20.0130.00815.93
5.6.10.0120.00815.93
5.6.00.0140.00815.92
5.5.380.0150.00715.84
5.5.370.0130.00815.79
5.5.360.0140.00815.71
5.5.350.0130.01015.75
5.5.340.0130.00915.72
5.5.330.0150.00715.73
5.5.320.0120.00915.79
5.5.310.0140.00815.77
5.5.300.0150.00715.55
5.5.290.0150.00715.58
5.5.280.0140.00715.56
5.5.270.0120.00815.55
5.5.260.0130.00815.53
5.5.250.0130.00815.55
5.5.240.0120.00915.59
5.5.230.0120.00815.57
5.5.220.0130.00715.55
5.5.210.0110.00915.58
5.5.200.0130.00715.54
5.5.190.0120.00915.51
5.5.180.0140.00715.51
5.5.170.0120.00815.75
5.5.160.0110.01015.54
5.5.150.0120.00815.50
5.5.140.0130.00715.48
5.5.130.0130.00815.47
5.5.120.0120.00815.49
5.5.110.0120.00915.50
5.5.100.0140.00815.50
5.5.90.0140.00715.56
5.5.80.0130.00715.51
5.5.70.0120.00815.58
5.5.60.0140.00615.56
5.5.50.0140.00615.55
5.5.40.0140.00715.56
5.5.30.0130.00815.55
5.5.20.0150.00715.53
5.5.10.0140.00615.55
5.5.00.0130.00815.48
5.4.450.0110.00613.20
5.4.440.0100.00613.25
5.4.430.0110.00613.21
5.4.420.0100.00613.25
5.4.410.0100.00613.19
5.4.400.0110.00513.20
5.4.390.0110.00713.13
5.4.380.0100.00713.16
5.4.370.0110.00513.14
5.4.360.0110.00513.15
5.4.350.0110.00613.16
5.4.340.0110.00513.19
5.4.330.0100.00613.14
5.4.320.0110.00613.14
5.4.310.0100.00613.16
5.4.300.0100.00513.18
5.4.290.0100.00613.14
5.4.280.0100.00613.14
5.4.270.0100.00513.17
5.4.260.0110.00613.16
5.4.250.0110.00613.18
5.4.240.0110.00513.13
5.4.230.0110.00513.10
5.4.220.0110.00613.13
5.4.210.0100.00613.10
5.4.200.0110.00613.10
5.4.190.0110.00513.10
5.4.180.0110.00513.11
5.4.170.0090.00713.16
5.4.160.0100.00613.12
5.4.150.0110.00613.13
5.4.140.0090.00713.13
5.4.130.0110.00613.18
5.4.120.0110.00613.17
5.4.110.0100.00613.19
5.4.100.0110.00513.22
5.4.90.0100.00713.15
5.4.80.0100.00613.22
5.4.70.0090.00713.22
5.4.60.0110.00613.25
5.4.50.0100.00613.18
5.4.40.0100.00613.18
5.4.30.0110.00513.27
5.4.20.0120.00513.22
5.4.10.0100.00613.24
5.4.00.0100.00713.12

preferences:
30.68 ms | 403 KiB | 5 Q