PHP 8.1: New Sodium XChaCha20
functions
Sodium extension in PHP 8.1 provides an XChaCha20 stream encryption algorithm, available since libsodium 1.0.12.
XChaCha20 is a stream cipher, and is a variant of the ChaCha20 algorithm. Sodium PHP extension already supports XChaCha20 with Poly1305 Message Authentication Code (MAC). In PHP 8.1, three new functions provide direct XChaCha20 functionality without authentication, also known as "detached mode".
Security Warning XChaCha20's encryption is unauthenticated. Without authentication, any decryption operation will be vulnerable to chosen-ciphertext attacks. PHP already provides Poly1305-authenticated XChaCha20 encryption with
sodium_crypto_aead_xchacha20poly1305_ietf_encrypt
/decrypt
functions, available since PHP 7.2.
sodium_crypto_stream_xchacha20_keygen
: Returns a secure random key for use withsodium_crypto_stream_xchacha20
.sodium_crypto_stream_xchacha20
: Expands the key and nonce into a keystream of pseudorandom bytes.sodium_crypto_stream_xchacha20_xor
: Encrypts a message using a nonce and a secret key (no authentication).
Additionally, there are two new PHP constants defined in the global namespace:
SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES
, assigned32
SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES
, assigned24
.
sodium_crypto_stream_xchacha20_keygen
The new sodium_crypto_stream_xchacha20_keygen
function in PHP 8.1's Sodium extension returns cryptographically secure random bytes of a length, suitable to be used with the XChaCha20 encryption.
sodium_crypto_stream_xchacha20_keygen
function synopsis
/**
* Returns a secure random key for use with @see sodium_crypto_stream_xchacha20
* @return string 32-byte secure random key
*/
function sodium_crypto_stream_xchacha20_keygen(): string {}
Return value will be of length SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES
constant, set to 32
. It will a binary string, that cannot be printed directly without encoding it as a base64, hex, or some sort of binary encoding.
base64_encode(sodium_crypto_stream_xchacha20_keygen());
// "b0C4GUTNmJ/xzcxoXT0hgWqH7xs78f1Tc4W/9sEldbM="
sodium_crypto_stream_xchacha20
The sodium_crypto_stream_xchacha20
function returns a pseudo random stream of bytes, that can be used to encrypt a message using the new sodium_crypto_stream_xchacha20_xor
function.
sodium_crypto_stream_xchacha20
function synopsis
/**
* Expands the key and nonce into a keystream of pseudorandom bytes.
* @param int $length Number of bytes desired
* @param string $nonce 24-byte nonce
* @param string $key Key, possibly generated from @see sodium_crypto_stream_xchacha20_keygen
* @return string Pseudorandom stream that can be used with @see sodium_crypto_stream_xchacha20_xor
*/
function sodium_crypto_stream_xchacha20(int $length, string $nonce, string $key): string {}
string $nonce
parameter must be a string containing 24 bytes (SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES
).string $key
parameter must be a string containing 32 bytes (SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES
).sodium_crypto_stream_xchacha20_keygen
generates a suitable key.
Usage example:
$key = sodium_crypto_stream_xchacha20_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES);
$stream = sodium_crypto_stream_xchacha20(8, $nonce, $key);
bin2hex($stream); // "27fa21568e076f7"
$stream = sodium_crypto_stream_xchacha20(11, $nonce, $key);
bin2hex($stream); // "727fa21568e076f7f496e4"
$stream = sodium_crypto_stream_xchacha20(12, $nonce, $key);
bin2hex($stream); // "727fa21568e076f7f496e4e9"
sodium_crypto_stream_xchacha20_xor
sodium_crypto_stream_xchacha20_xor
function encrypts/decrypts a given message using the nonce and key.
This encryption is unauthenticated, and does not prevent chosen-ciphertext attacks. Make sure to combine the ciphertext with a Message Authentication Code, for example with
sodium_crypto_aead_xchacha20poly1305_ietf_encrypt
/decrypt
functions, orsodium_crypto_auth
sodium_crypto_stream_xchacha20_xor
function synopsis
/**
* Encrypts a message using a nonce and a secret key.
* @param string $message Plain text or ciphertext
* @param string $nonce 24-byte nonce
* @param string $key Key, possibly generated from @see sodium_crypto_stream_xchacha20_keygen
* @return string Ciphertext or the plain-text
*/
function sodium_crypto_stream_xchacha20_xor(string $message, string $nonce, string $key): string {}
string $nonce
parameter must be a string containing 24 bytes (SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES
).string $key
parameter must be a string containing 32 bytes (SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES
).sodium_crypto_stream_xchacha20_keygen
generates a suitable key.
Usage example:
$key = sodium_crypto_stream_xchacha20_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES);
$message = 'PHP.Watch';
$ciphertext = sodium_crypto_stream_xchacha20_xor($message, $nonce, $key);
bin2hex($ciphertext); // "bbcebba4e3eefe0d69"
$message === sodium_crypto_stream_xchacha20_xor($ciphertext, $nonce, $key);
// true
Backwards Compatibility Impact
sodium_crypto_stream_xchacha20_keygen
, sodium_crypto_stream_xchacha20
, and sodium_crypto_stream_xchacha20_xor
are new functions added to PHP 8.1.
PECL extension libsodium
versions later than 2.0.23 will likely contain these new functions.
Alternately, the sodium_compat
library provides a polyfill for all of these functions on any PHP version since PHP 5.2.4.