Dans PHP, la fonction HASH_COPY est utilisée pour copier un contexte de hachage ( HashContext ), afin qu'il puisse créer une instance de calcul de hachage du même état sans modifier l'état de contexte d'origine. Pour les opérations de hachage dans des environnements multithreads, la sécurité et l'efficacité sont les points clés de l'attention des développeurs. Cet article explorera en détail la sécurité de la fonction HASH_COPY dans un environnement multithread et comment les meilleures pratiques sont effectuées.
Hash_Copy est une fonction introduite dans PHP 5.3.0 pour copier le contexte informatique du hachage:
<?php
$ctx1 = hash_init('sha256');
hash_update($ctx1, 'hello');
$ctx2 = hash_copy($ctx1);
hash_update($ctx2, ' world');
echo hash_final($ctx1); // hello valeur de hachage
echo "\n";
echo hash_final($ctx2); // hello world valeur de hachage
?>
HASH_COPY peut éviter de calculer à plusieurs reprises les données de hachage existantes et d'améliorer les performances en copie le contexte.
Le PHP n'est pas originaire d'un environnement multi-thread, mais le multi-threading peut être réalisé grâce à des extensions telles que des pthreads ou des swoole. À ce stade, plusieurs threads peuvent accéder à la même ressource de contexte de hachage en même temps.
hash_copy lui-même copie un objet d'état en mémoire. Si plusieurs threads partagent la même variable de contexte en même temps et ne les verrouillent pas, alors des conflits de lecture et d'écriture peuvent se produire, entraînant des conditions de race de données et produisent ainsi des résultats de hachage imprévisibles.
Cependant, si chaque thread détient indépendamment une copie de HashContext ou fonctionne indépendamment après la copie, les problèmes de sécurité du fil ne se produiront pas.
Les extensions de hachage PHP sont basées sur l'implémentation sous-jacente du langage C (OpenSSL ou bibliothèques de hachage intégrées). Habituellement, ces bibliothèques sont elles-mêmes en filetage, mais l'attention doit être accordée à:
Différentes versions de PHP ou d'extensions de hachage ont différentes garanties de sécurité de fil.
Les variables partagées en mode utilisateur doivent être protégées par elle-même via Mutexes ou d'autres mécanismes de synchronisation.
La fonction HASH_COPY elle-même est sûre, mais uniquement si plusieurs threads n'ont pas plusieurs threads fonctionnent simultanément la même instance de contexte de hachage . Le contexte copié peut être utilisé indépendamment dans chaque fil.
Pour s'assurer que la réplication du hachage est sûre et efficace dans un environnement multithread, les pratiques suivantes sont recommandées:
Après avoir initialisé le contexte du hachage, copiez-le via Hash_Copy et remettez-le à chaque fil pour une utilisation seul pour éviter la concurrence.
<?php
$ctx = hash_init('sha256');
hash_update($ctx, 'common part data');
$threads = [];
for ($i = 0; $i < 5; $i++) {
$threadCtx = hash_copy($ctx); // Chaque fil obtient une copie indépendante
// Ici, créons un fil et passons-le$threadCtx
// Continuez dans le fil hash_update Et enfin hash_final
}
?>
Si plusieurs threads doivent mettre à jour le même contexte, la protection Mutex doit être utilisée:
<?php
$mutex = new Mutex();
function safe_hash_update($ctx, $data, $mutex) {
$mutex->lock();
hash_update($ctx, $data);
$mutex->unlock();
}
?>
Cependant, les opérations de verrouillage fréquentes affecteront les performances et ne sont pas recommandées.
Passer des pointeurs de contexte de hachage non gâché provoque directement des problèmes de course. Une nouvelle copie doit toujours être générée avec hash_copy .
Si l'environnement le permet, vous pouvez utiliser directement les fonctions de hachage sans état (telles que le hash («Sha256», $ data) ) pour la chasse aux calculs afin d'éviter la complexité causée par le partage de l'état de contexte.
La fonction HASH_COPY elle-même est sûre et n'introduira pas les risques de sécurité multithreads.
Dans un environnement multi-thread, la clé est d'éviter le partage de threads multiples et l'exploitation de la même instance HashContext .
La meilleure pratique est: après la copie du contexte, il est remis à chaque thread pour une utilisation indépendante ou pour protéger le contexte partagé via un mécanisme de verrouillage.
Si possible, essayez d'utiliser une interface de hachage sans état pour simplifier le multithreading.