Skip to content
Extraits de code Groupes Projets
Valider 5e27fb3c rédigé par marcimat's avatar marcimat
Parcourir les fichiers

Chiffrement plus poussé : pad / unpad du message + hash si password (g0uZ)

- Utiliser sodium_pad et sodium_unpad sur le message à chiffrer
- Hacher un password en sha256 dans le chiffrement s’il sert comme clé.
C’est un compromis suffisant.
parent 75eed172
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -19,10 +19,8 @@ namespace Spip\Chiffrer;
* @link https://www.php.net/manual/fr/book.sodium.php
*/
class Chiffrement {
public static function keygen(): string {
return sodium_crypto_secretbox_keygen();
}
/** Chiffre un message en utilisant une clé (le secret_du_site par défaut) ou un mot de passe */
public static function chiffrer(
string $message,
#[\SensitiveParameter]
......@@ -33,14 +31,12 @@ class Chiffrement {
spip_log("chiffrer() sans clé `$message`", 'chiffrer' . _LOG_INFO_IMPORTANTE);
return null;
}
if (strlen($key) !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
while (strlen($key) < SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
$key .= $key;
}
$key = substr($key, 0, SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
if (strlen($key) !== \SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
$key = self::generateKeyFromPassword($key);
}
$nonce = random_bytes(\SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encrypted = sodium_crypto_secretbox($message, $nonce, $key);
$padded_message = sodium_pad($message, 16);
$encrypted = sodium_crypto_secretbox($padded_message, $nonce, $key);
$encoded = base64_encode($nonce . $encrypted);
sodium_memzero($key);
sodium_memzero($nonce);
......@@ -48,6 +44,7 @@ class Chiffrement {
return $encoded;
}
/** Déchiffre un message en utilisant une clé (le secret_du_site par défaut) ou un mot de passe */
public static function dechiffrer(
string $encoded,
#[\SensitiveParameter]
......@@ -58,16 +55,14 @@ class Chiffrement {
spip_log("dechiffrer() sans clé `$encoded`", 'chiffrer' . _LOG_INFO_IMPORTANTE);
return null;
}
if (strlen($key) !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
while (strlen($key) < SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
$key .= $key;
}
$key = substr($key, 0, SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
if (strlen($key) !== \SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
$key = self::generateKeyFromPassword($key);
}
$decoded = base64_decode($encoded);
$nonce = mb_substr($decoded, 0, \SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
$encrypted_result = mb_substr($decoded, \SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
$message = sodium_crypto_secretbox_open($encrypted_result, $nonce, $key);
$padded_message = sodium_crypto_secretbox_open($encrypted_result, $nonce, $key);
$message = sodium_unpad($padded_message, 16);
sodium_memzero($key);
sodium_memzero($nonce);
if ($message !== false) {
......@@ -78,6 +73,26 @@ class Chiffrement {
return null;
}
/** Génère une clé de la taille attendue pour le chiffrement */
public static function keygen(): string {
return sodium_crypto_secretbox_keygen();
}
/**
* Retourne une clé de la taille attendue pour le chiffrement
*
* Notamment si on utilise un mot de passe comme clé, il faut le hacher
* pour servir de clé à la taille correspondante.
*/
private static function generateKeyFromPassword(string $password): string {
if (strlen($password) === \SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
return $password;
}
$hashed = hash('sha256', $password);
return substr($hashed, 0, \SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
}
/** Retourne la clé de chiffrement par défaut (le secret_du_site) */
private static function getDefaultKey(): ?string {
$keys = SpipCles::instance();
return $keys->getSecretSite();
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter