Chiffrer tous les enregistrement d'un champ

r-one
Invité n'ayant pas de compte PHPfrance

14 janv. 2009, 18:58

Bonsoir !

Je dois, pour des raisons de sécurité, chiffrer +/- 10 000 enregistrements existants dans deux champs (injectés préalablement via csv).
J'ai beaucoup de mal à me décider sur le mode opératoire le plus efficace et optimisé.

Selon vous, faut-il mieux passer par une boucle PHP (php récupère les données, les chiffre et les renvoie à MySQL) ou une commande SQL existe-t-elle déjà ? Y a-t-il d'autres solutions ?

Merci
Erwan

r-one
Invité n'ayant pas de compte PHPfrance

14 janv. 2009, 20:46

Un début de solution : comment "passer" le champ dans la fonction ? Évidemment dans l'exemple suivant, ça ne peut pas marcher, "champ" n'étant pas une variable PHP…

mysql_query("UPDATE table SET champ=".chiffrer(champ)."") or die…

Eléphant du PHP | 170 Messages

14 janv. 2009, 22:02

Bonsoir,
une commande SQL existe-t-elle déjà ?
Des fonctions mysql de chiffrements sont proposées :
http://dev.mysql.com/doc/refman/5.0/fr/ ... tions.html

Si tu trouves ton bonheur dans la liste, tu peux faire ta modif en une seule requête :
( exemple avec SHA-1 )
mysql_query('UPDATE ta_table SET ton_champ1=SHA1(ton_champ1), ton_champ2=SHA1(ton_champ2)');
( sauvegarde ta table avant par précaution ;) )

ViPHP
AB
ViPHP | 5818 Messages

14 janv. 2009, 22:10

http://dev.mysql.com/doc/refman/5.0/fr/update.html

Comme tu le vois dans la doc, si tu n'utilise pas la clause "where", tous les enregistrements seront mis à jours.

Pour un hashage tu peux faire :

Code : Tout sélectionner

$requete = "UPDATE table SET champ = sha1(champ)";
Pour un cryptage (pouvant être décrypté)

Code : Tout sélectionner

$cle = 'toto'; $requete = "UPDATE table SET champ = AES_ENCRYPT(champ, '".$cle."')";
Pour une bonne utilisation d' AES_ENCRYPT puis d' AES_DECRYPT, tes champs doivent être convertis avec un type blod avant l'update.

Faire une duplication de ta table avant, au cas où.

Edit : j'avais pas vu la réponse de blof qui va dans le même sens

r-one
Invité n'ayant pas de compte PHPfrance

14 janv. 2009, 22:29

Merci à vous !

J'avais effectivement pensé à cette solution, qui n'est malheureusement pas envisageable dans mon cas : en effet, les données des deux champs doivent êtres respectivement chiffrées en SHA-256 pour le premier et avec un algo perso (AES-256 adapté et modifié pour php) pour le second...

J'en reviens donc à :

1) La possibilité "d'échapper" du SQL dans ma fonction de chiffrage php :

Code : Tout sélectionner

mysql_query("UPDATE table SET champ=".chiffrer([b]champ[/b])."") or die…
2) Récupérer le contenu de mon champ dans un array et faire une boucle d'insertion… (j'ai peur que ça soit assez lourd sur 10 000 enregistrements)

Donc, laquelle de ces deux solutions et comment ? :)

Merci encore.

ViPHP
AB
ViPHP | 5818 Messages

14 janv. 2009, 23:34

Si tu veux pas te casser la tête et que tu n'as pas à faire cet update souvent, utilises ton option 2.
Une boucle d'update sur 10000 enregistrements ne devrait pas prendre plus de quelques secondes.

r-one
Invité n'ayant pas de compte PHPfrance

14 janv. 2009, 23:36

Faute de mieux, je vais donc passer par la boucle (c'est lourd m'enfin...)

Code : Tout sélectionner

$sql_champs = mysql_query("SELECT champ FROM table"); for($i = 0; $champs[$i] = mysql_fetch_assoc($sql_champs); $i++); array_pop($champs); foreach ($champs as $champ) { $champ = $champ["champ"]; $champ_hash = hash('sha256', $champ); mysql_query("UPDATE table SET champ='$champ_hash' WHERE id='$champ'"); }
Des suggestions d'optimisation ?

ViPHP
AB
ViPHP | 5818 Messages

15 janv. 2009, 00:05

Je verrais plus un truc dans le genre :
$requete = mysql_query("SELECT id, champ FROM table");

while ($ligne = mysql_fetch_assoc($requete ))

{
$champ_code = hash('sha256', $ligne['champ']);

mysql_query("UPDATE table SET champ='".$champ_code."' WHERE id='".$ligne['id']."'");
}

r-one
Invité n'ayant pas de compte PHPfrance

15 janv. 2009, 00:47

En effet, ça à l'air beaucoup plus simple, par contre, je n'ai pas de champ "id" ou alors j'ai loupé un épisode :)

ViPHP
AB
ViPHP | 5818 Messages

15 janv. 2009, 00:59

L'id c'est l'identifiant unique pour chaque ligne. Choisi un identifiant unique a la place d'id, quelque soit son nom. Peut-être qu'un de tes champ en est un ...

EDIT : Et au pire si tu n'en as pas de défini tu peux rajouter un identifiant auto incrémenté dans ta table très facilement.

r-one
Invité n'ayant pas de compte PHPfrance

15 janv. 2009, 02:22

Je m'en doutais un peu ;) Merci beaucoup pour le coup de main en tous cas !

Eléphant du PHP | 291 Messages

15 janv. 2009, 11:50

Je ne sais pas si ça peut t'aider / répondre à une de tes problématiques, mais tu peux aussi créer un trigger qui ferait ce job là, puis réimporter toutes tes données dans une copie de ta table, tu supprimes la table non cryptée puis tu renommes la nouvelle table cryptée avec le nom d'origine !