Master PHP Sodium: Install, Encrypt, Decrypt, and Use AEAD_AES_256_GCM

This guide explains how to install the PHP Sodium extension, perform basic encryption and decryption, generate cryptographically secure random data, and implement AES‑256‑GCM encryption with both Sodium and OpenSSL, including a discussion of the AAD parameter.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Master PHP Sodium: Install, Encrypt, Decrypt, and Use AEAD_AES_256_GCM

Overview

Sodium crypto library is a modern, easy‑to‑use PHP extension for encryption, decryption, signing, and hashing. It replaces the deprecated Mcrypt extension and has been bundled with PHP source since version 7.2. For earlier PHP versions, the extension must be installed separately along with the libsodium-devel system library.

Installation

sudo pecl install -f libsodium

Successful installation produces output similar to:

Build process completed successfully
Installing '/usr/local/php-7.4/lib/php/extensions/no-debug-non-zts-20190902/sodium.so'
install ok: channel://pecl.php.net/libsodium-2.0.23
You should add "extension=sodium.so" to php.ini

If the build fails, install the development package first: sudo apt install libsodium-dev After installing the package, enable the extension by adding extension=sodium.so to php.ini and verify with:

php -m | grep sodium

Basic Encryption / Decryption

Encryption

<?php
/**
 * @desc libsodium example
 */
require '../vendor/autoload.php';
$secretKey = sodium_crypto_secretbox_keygen();
$message = 'Sensitive 开源技术小栈';
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encryptedMessage = sodium_crypto_secretbox($message, $nonce, $secretKey);
var_dump($encryptedMessage);
?>

Typical output:

string(44) "�̥|}3�¢ҥ[zm񸗘 n؀\ƮV½¯C"

Decryption

$decryptedMessage = sodium_crypto_secretbox_open($encryptedMessage, $nonce, $secretKey);
var_dump($decryptedMessage);
?>

Typical output:

string(28) "Sensitive 开源技术小栈"

Generating Random Data

Random Bytes

Use \Sodium\randombytes_buf($num_bytes) to obtain a string of cryptographically secure random bytes.

$string = \Sodium\randombytes_buf($num_bytes);

Random Integer

Use \Sodium\randombytes_uniform($max) to get a uniformly distributed integer in the range 0 … $max‑1. Adding 1 yields a 1‑to‑100 range. $int = \Sodium\randombytes_uniform(100) + 1; Note that the upper bound is exclusive.

Random 16‑bit Integer

Use \Sodium\randombytes_random16() to obtain an integer between 0 and 65535 inclusive.

$tcp_port = \Sodium\randombytes_random16();

AEAD_AES_256_GCM Symmetric Encryption

Both the OpenSSL and Sodium extensions support the AES‑256‑GCM algorithm. The article provides two complete implementations.

Sodium Implementation

<?php
declare(strict_types=1);
/**
 * @desc AES‑256‑GCM encryption using Sodium
 */
function aes256gcm_encrypt(string $data, string $keygen, string $aad = ''): array {
    $iv = random_bytes(SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES);
    $encrypt = sodium_crypto_aead_aes256gcm_encrypt($data, $aad, $iv, $keygen);
    return [
        'iv' => sodium_bin2base64($iv, SODIUM_BASE64_VARIANT_ORIGINAL),
        'aad' => sodium_bin2base64($aad, SODIUM_BASE64_VARIANT_ORIGINAL),
        'cipher_text' => sodium_bin2base64($encrypt, SODIUM_BASE64_VARIANT_ORIGINAL),
    ];
}

function aes256gcm_decrypt(array $secretData, string $keygen) {
    $iv = sodium_base642bin($secretData['iv'], SODIUM_BASE64_VARIANT_ORIGINAL);
    $aad = sodium_base642bin($secretData['aad'], SODIUM_BASE64_VARIANT_ORIGINAL);
    $cipherText = sodium_base642bin($secretData['cipher_text'], SODIUM_BASE64_VARIANT_ORIGINAL);
    return sodium_crypto_aead_aes256gcm_decrypt($cipherText, $aad, $iv, $keygen);
}

function main(): void {
    if (!sodium_crypto_aead_aes256gcm_is_available()) {
        exit('Not support AES-256-GCM');
    }
    $keygen = sodium_crypto_aead_aes256gcm_keygen();
    $data = '开源技术小栈';
    $secretData = aes256gcm_encrypt($data, $keygen, 'tinywan');
    $plainText = aes256gcm_decrypt($secretData, $keygen);
    echo "[x] 加密原文:" . $data . PHP_EOL;
    echo "[x] 密文数据:" . json_encode($secretData) . PHP_EOL;
    echo "[x] 解密原文:" . $plainText . PHP_EOL;
}

main();
?>

Sample execution output:

[x] 加密原文:开源技术小栈
[x] 密文数据:{"iv":"KGMwg3PKlihp46qo","aad":"dGlueXdhbg==","cipher_text":"6oRb78FP33byDBhlBc0g6e7DYH0k3Oiethup+4YeWPN4Xw="}
[x] 解密原文:开源技术小栈

OpenSSL Implementation

<?php
declare(strict_types=1);
/**
 * @desc AES‑256‑GCM encryption using OpenSSL
 */
function aes256gcm_encrypt(string $data, string $keygen, string $aad = ''): array {
    $cipher = 'aes-256-gcm';
    $ivLen = openssl_cipher_iv_length($cipher);
    $iv = random_bytes($ivLen);
    $encrypt = openssl_encrypt($data, $cipher, $keygen, OPENSSL_RAW_DATA, $iv, $tag, $aad);
    return [
        'iv' => base64_encode($iv),
        'tag' => base64_encode($tag),
        'aad' => base64_encode($aad),
        'cipher_text' => base64_encode($encrypt),
    ];
}

function aes256gcm_decrypt(array $secretData, string $keygen) {
    $iv = base64_decode($secretData['iv']);
    $tag = base64_decode($secretData['tag']);
    $aad = base64_decode($secretData['aad']);
    $cipherText = base64_decode($secretData['cipher_text']);
    $cipher = 'aes-256-gcm';
    return openssl_decrypt($cipherText, $cipher, $keygen, OPENSSL_RAW_DATA, $iv, $tag, $aad);
}

function main(): void {
    $keygen = bin2hex(random_bytes(16)); // 32‑byte key for AES‑256‑GCM
    $data = '开源技术小栈';
    $secretData = aes256gcm_encrypt($data, $keygen, 'tinywan');
    $plainText = aes256gcm_decrypt($secretData, $keygen);
    echo "[x] 加密原文:" . $data . PHP_EOL;
    echo "[x] 密文数据:" . json_encode($secretData) . PHP_EOL;
    echo "[x] 解密原文:" . $plainText . PHP_EOL;
}

main();
?>

Sample execution output:

[x] 加密原文:开源技术小栈
[x] 密文数据:{"iv":"CUit1bBOIOOM4Oaa","tag":"hlyP0MpykCNekBd1Kkobdw==","aad":"dGlueXdhbg==","cipher_text":"ToKc2+rVh8udQa\/bUtKodoC+"}
[x] 解密原文:开源技术小栈

Additional Authenticated Data (AAD)

The $aad parameter is part of the authenticated data. It must be supplied unchanged during decryption; otherwise decryption fails. The article illustrates this with a WeChat public‑account scenario where the AAD value is the user’s ID. A legitimate user can decrypt the stored ciphertext because the same AAD is used, while an attacker with a different ID cannot.

When would you need to use AAD?

In the example, the AAD ties the encrypted article to a specific user, preventing other users from successfully decrypting it.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PHPencryptioncryptographyrandomAES-256-GCMSodium
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.