Extension PHP

mbcrypt

Guide complet d'intégration de l'extension native mbcryptload

PHP 8.0 → 8.5 Windows et Linux AES-256-GCM

À propos

Qu'est-ce que mbcrypt ?

mbcrypt est une extension native pour PHP, fournie sous forme de dll pour Windows et de module .so pour Linux, qui chiffre le code source d'une application PHP avant sa distribution, puis le déchiffre automatiquement et de façon transparente à l'exécution, sans jamais l'écrire en clair sur le disque.

La problématique

Lorsqu'une application PHP est livrée à un client, déployée chez un hébergeur tiers ou installée sur un serveur dont l'accès n'est pas entièrement maîtrisé, le code source reste par défaut lisible par quiconque accède au système de fichiers. Cette situation expose l'éditeur du logiciel à plusieurs risques concrets : copie ou revente non autorisée de l'application, rétro-ingénierie de la logique métier ou d'algorithmes propriétaires, altération du code pour contourner un mécanisme de licence, ou encore divulgation accidentelle de secrets (clés, identifiants, logique interne) intégrés au code source.

La réponse apportée par mbcrypt

mbcrypt répond à cette problématique en chiffrant chaque fichier PHP avec un algorithme robuste et authentifié (AES-256-GCM), ou, pour des besoins de compatibilité historique, avec un mode XOR simplifié. Le fichier chiffré demeure un fichier .php valide, déployé sans aucune modification de l'architecture applicative existante : à chaque appel, l'extension le déchiffre en mémoire, exécute le code, puis efface le contenu en clair sans jamais le persister sur le disque. Seul le détenteur du mot de passe (transmis via le code, php.ini ou une variable d'environnement) peut exécuter le fichier ainsi protégé.

Code source protégé

Le code livré n'est plus directement lisible ni modifiable par un tiers ayant accès au système de fichiers.

Déploiement inchangé

Le fichier chiffré reste un .php standard : aucune adaptation de l'hébergement ou de la structure du projet n'est nécessaire.

Chiffrement fort et authentifié

AES-256-GCM avec dérivation de clé PBKDF2 : toute altération du fichier chiffré est détectée et rejetée à l'exécution.

Avant de commencer

Prérequis pour utiliser l'extension

Cinq conditions doivent être réunies pour que mbcryptload fonctionne correctement. Elles sont identiques sous Windows et sous Linux ; seuls les noms de fichiers diffèrent.

PHP installé, version exacte

Une version comprise entre 8.0 et 8.5, en sachant s'il s'agit d'une build TS (thread-safe) ou NTS (non thread-safe) :

php -i | findstr "Thread Safety" (Windows)
php -i | grep "Thread Safety" (Linux)

Le bon binaire pour cette version

Une .dll (Windows) ou une .so (Linux) compilée exactement pour la version de PHP et le mode TS/NTS visés (voir Téléchargements).

Extension activée dans php.ini

Une ligne extension=php_mbcryptload (Windows) ou extension=mbcryptload (Linux), suivie du redémarrage du service concerné (Apache, PHP-FPM) ou d'une simple relance du CLI.

OpenSSL présent à l'exécution

libcrypto-3-x64.dll (Windows) ou libcrypto.so.3 (Linux), nécessaire au mode de chiffrement recommandé, AES-256-GCM.

Runtime C (Windows uniquement)

VCRUNTIME140.dll ainsi que les composants api-ms-win-crt-*.dll (Visual C++ Redistributable), déjà présents sur la plupart des postes Windows 10/11 récents.

Vérification finale

Une fois ces cinq points réunis :

php -m | findstr mbcryptload
php --ri mbcryptload

Binaires officiels

Téléchargements

Binaires précompilés pour PHP 8.0 à 8.5, disponibles en modes TS/NTS (Windows) et NTS/ZTS (Linux). Vérifiez systématiquement l'empreinte SHA-256 après téléchargement (fichier complet : CHECKSUMS.sha256.txt).

Charger une dll ou un .so qui ne correspond pas exactement à la version de PHP et au mode TS/NTS de votre installation empêche PHP de démarrer. Vérifiez systématiquement ces deux critères avant de copier un fichier.

Windows : extension mbcryptload (.dll)

Version PHPModeFichierTailleSHA-256 (début)
8.0.30TSphp_mbcryptload_php80_ts.dll40 Ko017d4b36838b118b…
8.0.30NTSphp_mbcryptload_php80_nts.dll40 Kofdb00fb372bd5ef5…
8.1.10TSphp_mbcryptload_php81_ts.dll40 Kod805d8c16dd96832…
8.1.10NTSphp_mbcryptload_php81_nts.dll40 Ko9a2dce955ddb4c11…
8.2.15TSphp_mbcryptload_php82_ts.dll40 Ko84e16e79df0e27c2…
8.2.15NTSphp_mbcryptload_php82_nts.dll40 Ko7d25b93cf3487a43…
8.3.16TSphp_mbcryptload_php83_ts.dll40 Ko23a728ed6c41912f…
8.3.16NTSphp_mbcryptload_php83_nts.dll40 Ko6aa3750254ed3310…
8.4.23TSphp_mbcryptload_php84_ts.dll40 Ko2f4b7e836dc95cd1…
8.4.23NTSphp_mbcryptload_php84_nts.dll40 Ko91f941ee11858883…
8.5.8TSphp_mbcryptload_php85_ts.dll44 Kofb735979c9972c4d…
8.5.8NTSphp_mbcryptload_php85_nts.dll40 Kof58393304bc1d4f4…

Encodeur CLI Windows (pour chiffrer des fichiers, voir ci-dessous) : mbcrypt.exe (72 Ko)

Linux : extension mbcryptload (.so)

Version PHPModeFichierTailleSHA-256 (début)
8.0.xNTSmbcryptload_php80_nts.so40 Koa29382a6f379f7ae…
8.0.xZTSmbcryptload_php80_zts.so40 Ko1679aa2264c0ac85…
8.1.xNTSmbcryptload_php81_nts.so36 Koad78c34a0c173983…
8.1.xZTSmbcryptload_php81_zts.so40 Kode2460914904cae0…
8.2.xNTSmbcryptload_php82_nts.so36 Ko0181bfeae1f6bed8…
8.2.xZTSmbcryptload_php82_zts.so40 Kob111b17a45d032f3…
8.3.xNTSmbcryptload_php83_nts.so36 Ko366ec0baf53e2477…
8.3.xZTSmbcryptload_php83_zts.so40 Ko2351aa4edb98624f…
8.4.xNTSmbcryptload_php84_nts.so36 Ko8eb983948789e17c…
8.4.xZTSmbcryptload_php84_zts.so40 Ko93c6ab125ce11328…
8.5.xNTSmbcryptload_php85_nts.so36 Ko6373827b2dda5bad…
8.5.xZTSmbcryptload_php85_zts.so40 Ko19457bc3015403a7…

Encodeur CLI Linux (lié statiquement, sans dépendance à l'exécution) : mbcrypt (4.3 Mo)

Installation

Intégrer l'extension sous Windows

1

Identifier la version de PHP et le mode TS/NTS

Depuis une invite de commandes :

php -v
php -i | findstr "Thread Safety"
2

Copier la dll correspondante dans ext\

Exemple pour PHP 8.3 en mode TS :

copy php_mbcryptload_php83_ts.dll C:\chemin\vers\php\ext\php_mbcryptload.dll
3

Activer l'extension dans php.ini

extension=php_mbcryptload
4

Vérifier le chargement

php.exe -m | findstr mbcryptload
php.exe --ri mbcryptload

La sortie de --ri doit afficher AES-256-GCM => enabled.

Si php -m ne liste pas mbcryptload, ou si PHP refuse de démarrer, la cause la plus fréquente est un mauvais choix TS/NTS ou une version de PHP qui ne correspond pas exactement à la dll utilisée : revoir l'étape 1.

Installation

Intégrer l'extension sous Linux

1

Identifier la version de PHP, le mode et le dossier d'extensions

php -v
php -i | grep "Thread Safety"
php -i | grep ^extension_dir
2

Copier la .so correspondante

Exemple pour PHP 8.3 en mode NTS :

sudo cp mbcryptload_php83_nts.so "$(php -i | grep ^extension_dir | awk '{print $3}')/mbcryptload.so"
3

Activer l'extension dans php.ini (CLI et FPM)

echo "extension=mbcryptload" | sudo tee /etc/php/8.3/cli/conf.d/20-mbcryptload.ini
echo "extension=mbcryptload" | sudo tee /etc/php/8.3/fpm/conf.d/20-mbcryptload.ini
sudo systemctl restart php8.3-fpm
4

Vérifier le chargement

php -m | grep mbcryptload
php --ri mbcryptload

Un fichier .so compilé pour une version et un mode donnés fonctionne sur toute distribution dont la glibc est égale ou plus récente que celle utilisée à la compilation. Il ne s'agit donc jamais d'une question de distribution (Ubuntu, Debian, RHEL...) en tant que telle, mais uniquement d'architecture CPU, de version de PHP, de mode et de version de glibc.

Utilisation

Chiffrer un fichier PHP

Le chiffrement s'effectue hors ligne, une seule fois, à l'aide de l'encodeur en ligne de commande (mbcrypt.exe / mbcrypt), jamais à l'exécution.

# Mode XOR historique (sans mot de passe, compatibilité V2 uniquement)
mbcrypt -o output.php source.php

# Mode AES-256-GCM (recommandé)
mbcrypt -p "mon-mot-de-passe" -o output.php source.php

# Dossier entier, traitement récursif
mbcrypt -r -p "mon-mot-de-passe" -o app_chiffree/ app_source/

XOR ou AES-256-GCM ?

XOR (historique)
  • Chiffrement simple et très rapide
  • Aucun mot de passe requis
  • Facile à casser, ne protège pas un secret réellement sensible
  • Conservé uniquement pour la compatibilité avec la V2

Le fichier chiffré demeure un .php valide, à déployer tel quel : aucune extension de fichier ni structure de dossier à modifier côté application.

Configuration

Fournir le mot de passe à l'exécution

1

Dans le code PHP (le plus flexible, par requête)

mbcryptload_set_password("mon-mot-de-passe");
require "module_chiffre.php";
2

Directive php.ini (recommandée : appel direct, aucun code requis)

mbcryptload.password = "mon-mot-de-passe"

PHP_INI_SYSTEM : non surchargeable par ini_set() ou .htaccess.

3

Variable d'environnement (pratique pour Apache / PHP-FPM)

MBCRYPTLOAD_PASSWORD=mon-mot-de-passe

Visible via phpinfo() et les outils système : la moins sûre des trois méthodes.

Ordre de priorité si plusieurs méthodes sont actives simultanément : 1 > 2 > 3

Tests

Tester que tout fonctionne

1

L'extension est bien chargée

php -m | findstr mbcryptload (Windows) / php -m | grep mbcryptload (Linux)

2

Le mode AES-256-GCM est actif

php --ri mbcryptload

Doit afficher AES-256-GCM => enabled. En son absence, l'extension n'a pas été compilée avec le support OpenSSL : seul le mode XOR sera disponible.

3

Chiffrer puis déchiffrer un fichier de test

mbcrypt -p "test-2026" -o demo.encrypted.php demo.php
php -r 'mbcryptload_set_password("test-2026"); require "demo.encrypted.php";'

Le script doit s'exécuter normalement, comme s'il n'avait jamais été chiffré.

4

Vérifier le rejet d'un mauvais mot de passe

Avec un mot de passe incorrect, le require doit échouer explicitement (erreur d'authentification GCM), et ne jamais exécuter silencieusement un contenu corrompu ou vide.

Référence

Format du fichier chiffré (V3) et sécurité

Tag "MB_ENC_V3"
9 o
Version + Méthode
2 o
Réservé
6 o
Sel PBKDF2
16 o
Nonce GCM
12 o
Tag auth. GCM
16 o
Données chiffrées (zlib + AES-256-GCM)
N o

Les champs colorés (sel, nonce, tag d'authentification) ne sont présents qu'en mode AES-256-GCM.

PBKDF2-SHA256, 100 000 itérations

Dérive une clé de 32 octets à partir du mot de passe, rendant une attaque par force brute extrêmement lente.

Sel aléatoire par fichier

Un même mot de passe produit une clé différente pour chaque fichier chiffré.

GCM = chiffrement authentifié

Un fichier corrompu ou modifié échoue explicitement au déchiffrement : jamais de résultat erroné silencieusement accepté.

Jamais écrit en clair sur disque

Le déchiffrement a lieu en mémoire, le temps de l'exécution, puis son résultat disparaît.

Production

Mettre à jour un binaire déjà en production

Remplacer un mbcryptload.so déjà chargé par des workers PHP-FPM actifs n'est jamais une simple copie de fichier : c'est une opération sensible au timing, à traiter avec la même rigueur qu'une migration de base de données en production.

Ne jamais faire cp nouveau.so /chemin/mbcryptload.so directement sur un système où php-fpm tourne. Un cp en place n'est pas atomique : pendant la fraction de seconde où le fichier est en cours d'écriture, un worker qui redémarre (pm = dynamic) peut charger un binaire tronqué et faire planter en boucle tous les workers du pool.

Option A : copie + mv atomique (recommandée, zéro downtime)

mv sur un même système de fichiers repose sur l'appel système rename(), atomique par construction : un worker qui charge l'extension au même instant voit soit l'ancien fichier complet, soit le nouveau, jamais un état intermédiaire.

EXT_DIR=$(php -i | grep ^extension_dir | awk '{print $3}')
sudo cp mbcryptload_nouveau.so "$EXT_DIR/.mbcryptload.so.new"
sudo mv "$EXT_DIR/.mbcryptload.so.new" "$EXT_DIR/mbcryptload.so"

Les workers déjà démarrés gardent l'ancien binaire en mémoire (le fichier reste ouvert) ; seuls les prochains workers respawnés chargeront le nouveau. Pour forcer une bascule immédiate et homogène, enchaîner avec un redémarrage classique du pool une fois tous les fichiers remplacés.

Option B : arrêt du pool avant remplacement (plus simple, downtime bref)

sudo systemctl stop php8.3-fpm
sudo cp mbcryptload_nouveau.so "$(php -i | grep ^extension_dir | awk '{print $3}')/mbcryptload.so"
sudo systemctl start php8.3-fpm

Downtime de l'ordre de la seconde le temps du stop/start, à réserver aux fenêtres hors heures de pointe si le pool est partagé avec d'autres sites.

Vérification post-déploiement, dans tous les cas

sudo systemctl status php8.3-fpm --no-pager     # active (running), pas de boucle de restart
php8.3 -m | grep mbcryptload                    # extension chargée
sudo tail -20 /var/log/php8.3-fpm.log           # pas de "Terminating" en boucle
curl -sk -o /dev/null -w "%{http_code}\n" https://votre-domaine/

Production

Désactivation d'urgence (rollback)

Si un problème apparaît après une mise à jour, couper le chargement de l'extension est plus rapide et plus sûr qu'un rollback de binaire : le fichier .so lui-même n'est pas touché, seul son chargement au démarrage est désactivé.

# Par version PHP concernée (cli et fpm)
sudo mv /etc/php/8.3/fpm/conf.d/20-mbcryptload.ini /etc/php/8.3/fpm/conf.d/20-mbcryptload.ini.disabled
sudo mv /etc/php/8.3/cli/conf.d/20-mbcryptload.ini /etc/php/8.3/cli/conf.d/20-mbcryptload.ini.disabled
sudo systemctl restart php8.3-fpm

Réactivation : renommer .ini.disabled en .ini, puis redémarrer le pool FPM concerné. Aucune recompilation ni redéploiement de binaire n'est nécessaire pour revenir en arrière.

Production

Chiffrer une application déjà en production

Marche à suivre pour protéger le code source d'une application déjà déployée, sans interruption de service, avec un filet de sécurité à chaque étape.

1

Sauvegarde complète, avec vérification d'intégrité

Archiver l'application entière avant toute modification, puis vérifier que le nombre de fichiers dans l'archive correspond exactement au nombre de fichiers sur disque. Cette sauvegarde devient la seule copie en clair du code une fois le chiffrement effectué : la conserver hors du DocumentRoot.

2

Test sur un fichier isolé avant le traitement en masse

Chiffrer une copie d'un seul fichier, vérifier la présence du tag MB_ENC_V3 en tête de fichier, puis confirmer qu'il s'exécute correctement avec le mot de passe attendu, avant de lancer quoi que ce soit sur l'ensemble du code.

3

Chiffrement en place, fichier par fichier, toujours de façon atomique

Ne jamais écraser directement un fichier source par la commande de chiffrement elle-même. Chiffrer vers un fichier temporaire dans le même dossier, restaurer explicitement propriétaire et permissions d'origine (un mv ne les préserve pas), puis mv atomique par-dessus l'original (même principe que pour la mise à jour d'un .so ci-dessus).

MBCRYPT="/chemin/vers/mbcrypt"
PASSWORD="mot-de-passe"

find app/ routes/ -name "*.php" -print0 | while IFS= read -r -d '' f; do
  owner=$(stat -c '%U:%G' "$f"); mode=$(stat -c '%a' "$f")
  tmp="$(dirname "$f")/.$(basename "$f").tmp"
  "$MBCRYPT" -p "$PASSWORD" -o "$tmp" "$f" || { echo "ECHEC: $f"; rm -f "$tmp"; continue; }
  head -c9 "$tmp" | grep -q "MB_ENC_V3" || { echo "TAG INVALIDE: $f"; rm -f "$tmp"; continue; }
  chown "$owner" "$tmp"; chmod "$mode" "$tmp"
  mv "$tmp" "$f"
done

Un fichier déjà chiffré est ignoré automatiquement par mbcrypt (protection anti double-chiffrement intégrée) : relancer le script sur un dossier partiellement traité ne présente aucun risque.

4

Vider les caches applicatifs et recharger

Vider tout cache de configuration/routes/vues de l'application, puis redémarrer le pool PHP-FPM concerné : indispensable si l'opcache tourne avec validate_timestamps désactivé en production.

5

Vérification, dans l'ordre

Tag MB_ENC_V3 présent sur tous les fichiers ciblés, puis une commande qui charge réellement les classes chiffrées (pas seulement une vérification de syntaxe), puis le site réel en HTTP, puis tout worker en file d'attente redémarré à froid, pour prouver le rechargement depuis le disque et pas seulement la mémoire d'un process déjà démarré avant le chiffrement.

Avec un superviseur de process (type Supervisor), le nom adressable complet d'un worker est généralement <groupe>:<groupe>_00, pas le nom du groupe seul : une commande de redémarrage sur le mauvais nom échoue souvent silencieusement, sans rien redémarrer.

Une question ?

Nous contacter à propos de mbcrypt

Question technique, besoin d'une version personnalisée ou d'un accompagnement à l'intégration, écrivez-nous.

Besoin d'une extension sur mesure ?

KALYA TECHNOLOGIES conçoit et intègre des outils logiciels spécifiques pour vos besoins de sécurité, de déploiement ou d'automatisation.