March 30, 2020

PHP Encryption with Libsodium

PHP Development

What Is Libsodium?

Libsodium, also known as Sodium, is a powerful cryptography library. It is a portable, cross-compilable, installable, and packageable fork of NaCl, a famous cryptographic tool designed by Prof. D.J. Bernstein. If you need to enable PHP encryption/decryption, you can use Libsodium.

What Algorithms Are in Libsodium?

The Libsodium library is an “opinionated” cryptography library. This means the algorithms in Sodium have been selected and cannot be changed.

The library uses some of the most robust algorithms available, including:

If you need to use different algorithms — for instance, if you need to ensure compatibility with existing cryptosystems — you need to look for a different library, such as OpenSSL.

Libsodium Is Designed to Prevent Side-Channel Attacks

Apart from the selection of the best algorithms available, Sodium, and NaCl, were designed to prevent side-channel attacks. This is a very good point for security because the majority of attacks are based on issues in the implementations, rather than weaknesses in the algorithm itself.

Just to give you an idea, one of the most successful side-channel attacks in history was performed by Adi Shamir, Eran Tromer, and Dag Arne Osvik in 2006. The attack was aimed to discover, in **65 milliseconds,** the secret key used in widely deployed software for hard-disk encryption. (Here is the extended article.)

PHP Encryption With Libsodium

Developers can use Sodium for PHP encryption and decryption with PHP 7.2 and newer without an extension. If you want to use Sodium with PHP 7.0 or 7.1, you need to install a PECL extension.

Libsodium vs. OpenSSL

When comparing Libsodium vs. OpenSSL with the chart below, you can see that there are many differences between the two cryptographic libraries.

Libsodium vs. OpenSSL
Development LanguageCC
Software LicenseISC LicenseApache License, BSD License
Last UpdatedDecember, 2017March, 2020
Code Size44 kSLOC472 kSLOC
Key Generation/ExchangeECDHECDH, DH, DSA, RSA
Elliptic Curve CryptographyNISTNIST, SECG, ECC Brainpool, ECDSA, ECDH, Curve25519, EdDSA, GOST R 34.10
Public Key Cryptography Standardsn/aPKCS#1, PKCS#5, PKCS#8, PKCS#12, ASN.1
Hash FunctionsSHA-2MD5, SHA-1, SHA-2, SHA-3, RIPEMD-160, Tiger, Whirlpool, GOST, BLAKE2
Block Cipher AlgorithmsAESAES, Camellia, 3DES, Blowfish, CAST5, IDEA, GOST 28147-89/GOST R 34.12-2015 ARIA
Cipher ModesCTR, GCMECB, CBC, OFB, CFB, CTR, CCM, GCM, OCB, XTS, AES-Wrap, Stream
Stream CiphersSalsa20, ChaChaRC4, ChaCha

*information via comparison of cryptography libraries on wikipedia

Libsodium Examples

Here are six examples for using the Sodium cryptography library:

  • Encrypt/Authenticate with a shared key: To encrypt and/or authenticate a string using a shared-key, such as symmetric encryption, Sodium uses the XSalsa20 algorithm to encrypt and HMAC-SHA512 for the authentication.
  • Sending secret messages: To encrypt a message in an end-to-end scenario, such as when a user wants to send a secret message to another user, Sodium uses the algorithms XSalsa20 to encrypt, Poly1305 for MAC, and XS25519 for key exchange.
  • Digital signature: To generate a digital signature for a string, such as a message/file, Sodium uses an Elliptic Curve algorithm, Ed25519.
  • Authenticated encryption with AES-GCM: Sodium offers authenticated encryption using the AES algorithm with Galois/Counter Mode (GCM).
  • Store passwords safely: This is an important topic for PHP developers. The first suggestion is to never encrypt it, always store a hash value of the password. The hash algorithm used by Sodium is Argon2i. This algorithm is resistant to side-channel attacks and GPU-cracking attacks.
  • Derive a key from a user's password: Generate an encryption key starting from a user's password using the Argon2i algorithm. Remember to never use a user's password as the encryption key!

Libsodium PHP String Encrypt Example

The Sodium APIs are quite simple to use. Just to give you an idea, here’s example code on how to encrypt a PHP string with a shared-key:

$msg = 'This is a super secret message!';

// Generating an encryption key and a nonce
$key   = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES); // 256 bit
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); // 24 bytes

// Encrypt
$ciphertext = sodium_crypto_secretbox($msg, $nonce, $key);
// Decrypt
$plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);

echo $plaintext === $msg ? 'Success' : 'Error';


And here how to authenticate a message (without encryption):

$msg = 'This is the message to authenticate!';
$key = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES); // 256 bit

// Generate the Message Authentication Code
$mac = sodium_crypto_auth($msg, $key);

// Altering $mac or $msg, verification will fail
echo sodium_crypto_auth_verify($mac, $msg, $key) ? 'Success' : 'Error';


To see more PHP code examples, see the slides from this ZendCon  and OpenEnterprise presentation.

Want to learn how Zend by Perforce can help you with your security strategy?

See Consulting Services

Additional Resources