← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

PHP Sodium Extension (Libsodium)

PHP PHP 7.2+ Advanced
debt(d7/e3/b3/t5)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). Nonce reuse, hardcoded keys, and unchecked return values from sodium_crypto_secretbox_open() are not caught by standard PHP linters; SAST tools like Psalm/Phan don't flag cryptographic misuse by default. Code review catches these.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). quick_fix describes replacing openssl_encrypt()+HMAC with sodium_crypto_secretbox() — a pattern swap, not a single line, but contained to crypto call sites.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Sodium usage is typically confined to a crypto/auth module; applies_to is web/cli but the choice doesn't shape the whole system — it's a library swap with a small surface.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5). The misconception about installation is minor, but sodium_crypto_secretbox_open() returning false instead of throwing, plus nonce-uniqueness requirements, are documented gotchas developers must learn — contradicts exception-based error handling expected elsewhere in modern PHP.

About DEBT scoring →

Also Known As

libsodium PHP sodium PHP sodium_crypto PHP modern crypto

TL;DR

The Sodium extension (bundled since PHP 7.2) provides modern, misuse-resistant cryptography via the libsodium C library — covering authenticated encryption, key exchange, password hashing with Argon2, and digital signatures with a simple, safe API.

Explanation

Libsodium is an opinionated cryptography library that deliberately offers only modern, well-analysed algorithms — there are no knobs to configure cipher modes, key sizes, or padding, because the library makes the right choices for you. PHP's Sodium extension wraps it directly. For symmetric encryption, sodium_crypto_secretbox() uses XSalsa20-Poly1305 — an authenticated encryption scheme that provides both confidentiality and integrity in one function. For asymmetric encryption, sodium_crypto_box() uses X25519+XSalsa20-Poly1305. Password hashing uses Argon2id. Key generation uses /dev/urandom via sodium_crypto_secretbox_keygen(). The extension is bundled with PHP 7.2+ and requires no installation on modern systems.

Common Misconception

You need to install the Sodium extension separately. It has been bundled with PHP since 7.2 and enabled by default. On older systems, install php-sodium via your package manager — it is not a PECL extension.

Why It Matters

OpenSSL gives you enough rope to hang yourself — wrong cipher mode choices, missing authentication, incorrect IV handling, and padding oracle vulnerabilities are all possible. Sodium's API is designed so that doing the wrong thing requires explicit effort. For new PHP applications needing encryption, Sodium should be the default choice.

Common Mistakes

  • Reusing nonces with the same key — each encryption must use a unique nonce; use random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES) each time.
  • Storing the key in source code or configuration files — use environment variables or a secrets manager (HashiCorp Vault, AWS Secrets Manager).
  • Using sodium for password hashing when Argon2 via password_hash() would do — password_hash(PASSWORD_ARGON2ID) is simpler for storing user passwords; Sodium's API is better for general-purpose authenticated encryption.
  • Forgetting to check the return value of sodium_crypto_secretbox_open() — it returns false on authentication failure, not an exception; always check.

Code Examples

✗ Vulnerable
<?php
// ❌ OpenSSL with common mistakes — ECB mode, no authentication
$key = 'mysecretkey12345'; // Weak key, wrong length
$encrypted = openssl_encrypt(
    $plaintext,
    'AES-128-ECB',   // ECB mode — reveals patterns in data
    $key
    // No IV, no authentication tag — malleable ciphertext
);
✓ Fixed
<?php
// ✅ Sodium — authenticated encryption, correct by default
$key = sodium_crypto_secretbox_keygen(); // 256-bit random key
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); // 192-bit nonce

$ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key);
// $ciphertext is encrypted AND authenticated — any tampering is detected on decrypt

// Store: base64_encode($nonce . $ciphertext)

$combined = base64_decode($stored);
$nonce     = substr($combined, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ct        = substr($combined, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

$plaintext = sodium_crypto_secretbox_open($ct, $nonce, $key);
if ($plaintext === false) {
    throw new RuntimeException('Decryption failed — data tampered or wrong key');
}

Added 23 Mar 2026
Views 39
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 1 ping T 0 pings W 2 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Google 6 Amazonbot 6 Perplexity 4 Ahrefs 3 Scrapy 3 Meta AI 2 Bing 2 ChatGPT 1 Claude 1 SEMrush 1 PetalBot 1
crawler 28 crawler_json 2
DEV INTEL Tools & Severity
⚙ Fix effort: Medium
⚡ Quick Fix
Replace openssl_encrypt() + manual HMAC patterns with sodium_crypto_secretbox() — it handles encryption and authentication in one call. Generate keys with sodium_crypto_secretbox_keygen() and store them in environment variables.
📦 Applies To
PHP 7.2+ web cli


✓ schema.org compliant