2009-05-23 2 views
2

В моей программе мы сохраняем IP-адрес пользователя в записи. Когда мы показываем список записей пользователю, мы не хотим передавать IP-адрес другого пользователя, поэтому мы SHA1 хешируем его. Затем, когда пользователь нажимает на записи, он переходит к URL, как это:SQL SHA1 внутри WHERE

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

Теперь мне нужно перечислить все записи по IP-адресу, указанному в хэш SHA1. Я пробовал:

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

но это не работает. Как мне это сделать?
Thanks, Isaac Waller

+1

Почему вы просто используете хеш вместо самого IP-адреса? – Gumbo

+0

С помощью этого подхода вы вычисляете SHA1 всех адресов в базе данных каждый раз, когда выполняете запрос. Это будет удивительно медленным и использовать огромное количество CPU. – blueshift

ответ

4

Я бы хранить SHA1 от IP в базе данных вместе с сырым IP, так что запрос стал бы

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

Тогда я убедиться, что расчет SHA1 происходит ровно одно место в коде, так что нет возможности для этого сделать несколько иначе в разных местах. Это также дает вам возможность смешать соль в расчете, чтобы кто-то не мог просто вычислить SHA1 по интересующему их IP-адресу и передать это вручную.

Хранение хэша SHA1 также дает вам возможность добавить вторичный индекс на ip_sha1 для ускорения этого SELECT. Если у вас очень большой набор данных, выполнение SHA1 в предложениях WHERE заставляет базу данных выполнять полное сканирование таблицы, а также повторять вычисления для каждой записи при каждом сканировании.

+0

+1: DRY (Do not Repeat Yourself) является принципом * ключа * и гарантирует, что каждая ключевая часть данных или кода существует только один раз, то есть в «точно одном месте», как вы выразились, важная часть СУХОЙ. –

+0

Мне нужен исходный IP-адрес сам, но не хочу делиться им с публикой. –

+0

@ Исаак Уоллер: Вы можете хранить как IP, так и его хэш в таблице. Это ускорит поиск и облегчит поиск неисправностей. – Andomar

0

Вы сравнили выход вашего хэш-алгоритма с выходом MySQL SHA1()? Например, для IP-адреса 1.2.3.4?

3

Каждый раз, когда у меня было непредвиденное несоответствие хэширования, это произошло потому, что я случайно хэшировал строку, содержащую некоторые пробелы, такие как «\n».

+0

+1 Правильно ... Я помню, что – Andomar

7

Не знаю, имеет ли значение, но ваш SHA1 hash da39a3ee5e6b4b0d3255bfef95601890afd80709 - это хорошо известный хэш пустой строки.

Это просто пример или вы забыли указать фактический адрес IP для функции вычисления хэша?

Update:

ли генерировать код веб-страницы SHA1 хэшей в нижнем регистре?

Эта проверка потерпит неудачу в MySQL:

SELECT SHA1('') = 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709' 

В этом случае, используйте:

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

, что получится.

Кроме того, вы можете заранее рассчитать хэш SHA1 при вставке записи в таблицу:

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 

Это вернет вам оригинальную IP и индексировать ip_sha, так что этот запрос будет работать быстро.

+0

Это был всего лишь пример. –

3

Просто быстрая мысль: это очень простая обфускация. Есть только 2 возможных IP-адресов, поэтому, если кто-то с техническими знаниями хотел бы разобраться в этом, они могли бы сделать это, вычислив все 4 миллиарда хэшей, что не займет много времени. В зависимости от чувствительности этих IP-адресов вам может потребоваться частная таблица поиска.

+1

Или соль, по крайней мере. – blueshift

0

Я закончил шифрование IP-адресов и расшифровал их на другой странице. Тогда я могу просто использовать необработанный IP-адрес в SQL-запросе. Кроме того, он защищает от нападений грубой силы, например, Autocracy.

Смежные вопросы