3v4l.org

run code in 300+ PHP versions simultaneously
<?php $password = 'My Plaintext Password'; $plaintext = 'This is my message'; $secretBox = new Secretbox(); $ciphertext = $secretBox->encrypt($plaintext, $password); var_dump($ciphertext); $decryptedPlaintext = $secretBox->decrypt($ciphertext, $password); var_dump($decryptedPlaintext); assertThat($decryptedPlaintext === $plaintext, 'Can decrypt'); assertThat( $secretBox->encrypt($plaintext, $password) !== $secretBox->encrypt($plaintext, $password), 'Should not result in same ciphertext' ); try { $failed = false; // modify ciphertext $ciphertext[65] = 'f'; $secretBox->decrypt($ciphertext, $password); } catch (\Exception $e) { $failed = true; } finally { assertThat($failed, 'Tempered chiphertext should result in exception'); } class Secretbox { public function encrypt(string $plaintext, string $password): string { // create a random salt for key derivation $salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES); $key = $this->deriveKeyFromUserPassword($password, $salt); $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); $ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key); sodium_memzero($password); sodium_memzero($key); return $salt.$nonce.$ciphertext; } public function decrypt(string $ciphertext, string $password): string { $salt = substr($ciphertext, 0, SODIUM_CRYPTO_PWHASH_SALTBYTES); $nonce = substr($ciphertext, SODIUM_CRYPTO_PWHASH_SALTBYTES, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); $ciphertext = substr($ciphertext, SODIUM_CRYPTO_PWHASH_SALTBYTES + SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); $key = $this->deriveKeyFromUserPassword($password, $salt); $plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key); sodium_memzero($password); sodium_memzero($key); sodium_memzero($nonce); if ($plaintext === false) { throw new \InvalidArgumentException('Bad ciphertext'); } return $plaintext; } private function deriveKeyFromUserPassword(string $password, string $salt): string { $key = sodium_crypto_pwhash( SODIUM_CRYPTO_SECRETBOX_KEYBYTES, $password, $salt, SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE ); sodium_memzero($password); return $key; } } function assertThat(bool $expressionResult, string $message) { if (!$expressionResult) { throw new \RuntimeException($message); } }
Output for 7.4.0
string(74) " D�j|����������d���c�B���O���"�?�?8�ÞD)V�h�}m��7zCҵ��2�H1굁0x" string(18) "This is my message"
Output for 7.3.12
string(74) " ݹ%Hi��^#���g�*�e�P��F\�L��?��sK�z<U�4�{�N&��MIԘM��Ŭ�8U�����!t�" string(18) "This is my message"
Output for 7.3.11
string(74) "�[�u���z��(�� -����Zؘ�+O�����6�Dl�kX�D��t��="$�+\�w8���s�j1�" string(18) "This is my message"
Output for 7.3.10
string(74) "��9rb�[d�韢�h#� �p�����ѕ�a~���G��jm�T��c��\��׭rh��p���7x@�A)2" string(18) "This is my message"
Output for 7.3.9
string(74) ")�%�*�C���\�hZ�A���U���s��Ð)�+8]u ���?���B:bl�0����T�������+^" string(18) "This is my message"
Output for 7.3.8
string(74) "�(�&�1���.d|���?!��!��-�.5 4����><�L�0���)�FAi����<��~A+��+ź�Uw�Ȭ�" string(18) "This is my message"
Output for 7.3.7
string(74) "���B��pU���<dfs�zJ� Ց� 8�P2$�����[8?��eO�p����Ƥ/l�"���%pm�." string(18) "This is my message"
Output for 7.3.6
string(74) "Nb_݄�W�m�T&��U��z�g�R�����J��c1׏��UO$��C�k%�F�+Bu#�Зa:�E" string(18) "This is my message"
Output for 7.3.5
string(74) "ԅPBBʸyS)zT��,Lu�(ig�S�^� F�{�O���l�\rq4(�nv����zݘL�`����o�"�Ҁ" string(18) "This is my message"
Output for 7.3.4
string(74) "^���{���kd�M���Q���M�;mT�c�/� �dWn�c{o.m��p|m���ݿ��j�S��q" string(18) "This is my message"
Output for 7.3.3
string(74) "���Ae J�r���<���Y��S+�>� �,�y�4��� �����#��՝�j�����9ю���v$�}" string(18) "This is my message"
Output for 7.3.2
string(74) "4��ke�W��1��#�$�x�י0�Lnc���&bG��\�|�;�$DUT����C�s��Z0�� Y��&����" string(18) "This is my message"
Output for 7.3.1
string(74) "�!k���*��=��2%���1ϛ��N�N�(� ��@ͻ�Z�߿��uZo|�hM�u����\^����:" string(18) "This is my message"
Output for 7.3.0
string(74) "�� "�qO�>���� `�8\� YmuɅ��-�P�#J�f9�cu���+(D��B��[���A�R�2�a��m�" string(18) "This is my message"
Output for 7.2.25
string(74) "2U��Ey�0�������xM�/5g�Y��G�Y"<�*�"Znnr^ ��nHg,�@�fయZ�����O�" string(18) "This is my message"
Output for 7.2.24
string(74) "Fl��c�`\E�gP�� f��P�� �Cy{���k w�CY�J�3m��n�@���8�hvs^��>�1" string(18) "This is my message"
Output for 7.2.23
string(74) "�G��"@ ��� �u$:��P��:�ix�f�-�r~,�ڷ��xp�zH�QK�P-� �'�*�J�ԤW� E" string(18) "This is my message"
Output for 7.2.22
string(74) "������ PT�eI��ڀ)�3]��m"z����j3�#N��4�vD ���Ł�9.�J�c�7��1��n���" string(18) "This is my message"
Output for 7.2.21
string(74) "u[ �̡ѝӰ�3�Ռ�y���P?L�yO�O@e��%G��a��T;�S�"�a�~�.l�/�o��_� ���" string(18) "This is my message"
Output for 7.2.20
string(74) "@~��=�����ٻ�p�o��˦D�cS� ��DƼ$%�R�2��P^u�42�k��ɩi9��l��ٛT2`�j �" string(18) "This is my message"
Output for 7.2.19
string(74) "*��@��TeS� �w���)��n�\�j!��X~�W�9eF��⊅���3n��#��N�� ߋ���:� �" string(18) "This is my message"
Output for 7.2.18
string(74) "��MbO����}�=ɩW�����wq�b,��w�d�^���B%��OB����T�\��TrPd��, �%S�" string(18) "This is my message"
Output for 7.2.17
string(74) "�\�S�)�֐�rV������9�����M�'� ռS�|;�f�J�ύB � ��5�D���j 2H��8" string(18) "This is my message"
Output for 7.2.0
string(74) "�B�>�U��9��~��r?,�E��E"� �� �Y�����Z]�u�ᢕ"�)5���"��j���(���b� " string(18) "This is my message"
Output for 7.1.0 - 7.1.33
Notice: Use of undefined constant SODIUM_CRYPTO_PWHASH_SALTBYTES - assumed 'SODIUM_CRYPTO_PWHASH_SALTBYTES' in /in/XSCbd on line 41 Fatal error: Uncaught TypeError: random_bytes() expects parameter 1 to be integer, string given in /in/XSCbd:41 Stack trace: #0 /in/XSCbd(41): random_bytes('SODIUM_CRYPTO_P...') #1 /in/XSCbd(7): Secretbox->encrypt('This is my mess...', 'My Plaintext Pa...') #2 {main} thrown in /in/XSCbd on line 41
Process exited with code 255.

preferences:
52.98 ms | 441 KiB | 5 Q