2009-05-23 29 views
2

Dans mon programme, nous stockons l'adresse IP d'un utilisateur dans un enregistrement. Lorsque nous affichons une liste d'enregistrements à un utilisateur, nous ne voulons pas donner l'adresse IP de l'autre utilisateur, donc nous l'avons haché par SHA1. Ensuite, lorsque l'utilisateur clique sur un enregistrement, il va à une URL comme ceci:SQL SHA1 inside OERE

http://www.example.com/allrecordsbyipaddress.php?ipaddress=SHA1HASHOFTHEIPADDRESS 

Maintenant, je dois énumérer tous les enregistrements de l'adresse IP spécifiée dans le hachage SHA1. J'ai essayé ceci:

SELECT * FROM records 
WHERE SHA1(IPADDRESS)="da39a3ee5e6b4b0d3255bfef95601890afd80709" 

mais cela ne fonctionne pas. Comment ferais-je cela?
Merci, Isaac Waller

+1

Pourquoi utilisez-vous simplement un hachage à la place de l'adresse IP elle-même? – Gumbo

+0

Avec cette approche, vous calculez le SHA1 de toutes les adresses de la base de données chaque fois que vous effectuez une requête. Ce sera incroyablement lent et utiliser de grandes quantités de CPU. – blueshift

Répondre

4

Je stocke l'SHA1 de l'IP dans la base de données ainsi que la première IP, de sorte que la requête deviendrait

SELECT * FROM records WHERE ip_sha1 = "..." 

Je ferais en sorte que le calcul de SHA1 se exactement un endroit dans le code, de sorte qu'il n'y a aucune possibilité pour qu'il soit fait légèrement différemment à plusieurs endroits. Cela vous donne également l'occasion de mélanger un sel dans le calcul, de sorte que quelqu'un ne peut pas simplement calculer le SHA1 sur une adresse IP qui l'intéresse et le transmettre à la main.

Le stockage de la base de données SHA1 vous donne également la possibilité d'ajouter un index secondaire sur ip_sha1 pour accélérer ce SELECT. Si vous disposez d'un ensemble de données très volumineux, l'exécution de SHA1 dans les clauses WHERE force la base de données à effectuer une analyse complète de la table, ainsi qu'à refaire un calcul pour chaque enregistrement de chaque analyse.

+0

+1: DRY (Ne vous répétez pas) est un principe * clé *, qui garantit que chaque donnée clé ou code n'existe qu'une seule fois, c'est-à-dire "exactement à un endroit" comme vous le dites, une partie cruciale de DRY. –

+0

J'ai moi-même besoin de l'adresse IP brute, mais je ne veux pas la partager avec le public. –

+0

@Isaac Waller: Vous pouvez stocker à la fois l'adresse IP et son hachage dans la table. Cela rendrait les recherches plus rapides et faciliterait le dépannage. – Andomar

0

Avez-vous comparé la sortie de votre algorithme de hachage avec la sortie de SHA1 de MySQL()? Par exemple pour l'adresse IP 1.2.3.4?

3

Chaque fois que j'ai eu une incompatibilité de hachage inattendue, c'est parce que j'ai accidentellement haché une chaîne qui comprenait des espaces, tels que "\n".

+0

+1 À droite ... Je me souviens que – Andomar

7

Je ne sais pas si ça compte, mais votre SHA1 hachage da39a3ee5e6b4b0d3255bfef95601890afd80709 est un hachage bien connu d'une chaîne vide.

Est-ce juste un exemple ou vous avez oublié de fournir une adresse réelle IP à la fonction de calcul de hachage?

Mise à jour:

Est-ce que votre code de page Web SHA1 générer hash en minuscules?

Cette vérification échouera dans MySQL:

SELECT SHA1('') = 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709' 

Dans ce cas, utilisez ceci:

SELECT SHA1('') = LOWER('DA39A3EE5E6B4B0D3255BFEF95601890AFD80709') 

, qui succédera.

En outre, vous pouvez précalculer le hachage SHA1 lorsque vous insérez les enregistrements dans la table:

INSERT 
INTO ip_records (ip, ip_sha) 
VALUES (@ip, SHA1(CONCAT('my_secret_salt', @ip)) 

SELECT * 
FROM ip_records 
WHERE ip_sha = @my_salted_sha1_from_webpage 

Cela vous ramènera le IP et permettre l'indexation des ip_sha d'origine, de sorte que cette requête fonctionnera rapidement.

+0

C'était juste un exemple. –

3

Juste une petite remarque: c'est une obfuscation très simple. Il n'y a que 2 adresses IP possibles, donc si quelqu'un ayant des connaissances techniques voulait le comprendre, il pourrait le faire en calculant les 4 milliards de hachages, ce qui ne prendrait pas beaucoup de temps. Selon la sensibilité de ces adresses IP, vous pouvez envisager une table de recherche privée.

+1

Ou un sel, au moins. – blueshift

0

J'ai fini par crypter les adresses IP, et les décrypter sur l'autre page. Ensuite, je peux simplement utiliser l'adresse IP brute dans la requête SQL. En outre, il protège contre les attaques par force brute, comme Autocracy dit.