Идеи по созданию небольшого (<10 цифр) и не (очень) безопасного «хеша»

StackOverflow https://stackoverflow.com/questions/890907

Вопрос

Я работаю над онлайн-системой продажи билетов на мероприятия, где пользователи смогут самостоятельно распечатать свои билеты и появиться на мероприятии, где они будут отсканированы (штрих-код), и в идеале человек сможет войти.Моя проблема заключается в том, как создать «код билета», отвечающий следующим требованиям:

  • каждый «код билета» должен существенно отличаться друг от друга (т. е. не иметь последовательной нумерации)
  • в идеале билет будет сверяться с центральной базой данных, чтобы предотвратить повторное использование, но он ДОЛЖЕН иметь возможность работать и в автономном режиме, и в этом случае система должна проверить «действительный» код билета и то, что он не использовался в этот ворота.
  • «код билета» должен быть достаточно маленьким, чтобы его можно было легко ввести в случае необходимости.
  • владельцу билета понадобится только билет для входа (т. е. без проверки удостоверения личности)

Диапазон данных очень мал, всего будет около 20 мероприятий в течение 4 дней с примерно 5000 билетов на мероприятие (около 100 000 различных кодов билетов).

Теперь у меня есть несколько полей, которые не напечатаны в билете и неизвестны пользователю, и которые я могу использовать для кодирования части «кода билета», поэтому я мог бы использовать EventId, OrderId, EventDate и немного соли, чтобы создать небольшой " hash» для части кода (идеи?), но я все еще придерживаюсь последовательного идентификатора заявки или GUID (было бы слишком долго)

Есть идеи или подсказки, как это сделать?

Это было полезно?

Решение

Рассмотрим очень простую схему, основанную на сети Фейстеля, для изменения, скажем, идентификационного номера билета. Это сообщение (который присутствует в списках PostgreSQL, но не имеет к PostgreSQL особого отношения) описывает простой Сеть Фейстеля.На каждом билете вы можете напечатать идентификационный номер билета (выбираемый последовательно), а затем «секретный код билета», который является результатом передачи идентификационного номера через сеть Feistel.Возможные варианты включают добавление контрольной цифры к секретному коду и использование входных данных в сети Фейстеля не только на последовательно сгенерированном номере (число + 10 000 * идентификационный номер события и т. д.).

Другие советы

Зачем изобретать велосипед?Просто сделайте что-то вроде этого (код Python, спросите меня, если вам нужны разъяснения):

import hashlib

secretpassword = "blah"

def createticket(eventnum, ticketnum):
    m = hashlib.md5() # or any crypto hash you like
    m.update("%s%s%s" % (eventnum, ticketnum, secretpassword))
    return m.hexdigest()[:10]

Пример:

Событие номер 1

Билет № 123

createticket(1,123)
# output: 2d7f242597

Мистер билетер приходит со своим верификатором и вводит номер мероприятия/билета и хэш:

def verifier(eventnum, ticketnum, hash):
    return hash == createticket(eventnum, ticketnum)

verifier(1,123, "2d7f242597")
# ouput: True

Я предлагаю вам дать Алгоритм Верховева попытка.

Я вижу два способа:

  1. Сгенерируйте случайное число или, по крайней мере, случайную часть числа и сохраните его в центральной базе данных.Затем загрузите базу данных во все системы ворот для проверки.
  2. Количество должно быть самодостаточным.Другими словами, номер должен иметь возможность оформления без сохраненного списка.Это похоже на какую-то систему контрольных сумм.Например, вы можете ввести числа от 1 и выше, сделать их 5-значными (00000-99999 = 100 000 чисел) и добавить к ним 1-3 буквы, гарантируя, что в итоге вы получите контрольную сумму, которая будет проверена.

Для автономной проверки я вижу только одно простое решение..

Добавьте к идентификатору билета хэш идентификатора билета и соль для каждого события.Вы можете усечь любой криптографический хэш до желаемого размера.Я не могу придумать конкретной причины использовать что-либо, кроме случайного числа, для самого идентификатора базового билета.

Это позволяет вам ограничить размер идентификатора билета и иметь четко пропорциональную безопасность по отношению к размеру идентификатора билета.

Вы можете выполнить расчет CRC.

По сути, просто начните добавлять каждый символ в строку и ограничивайте длину длинным целым числом.

Вы можете начать с известного случайного числа и сохранить его в первых 4 байтах, а последние четыре — как расчет, как я описал ранее.

Это будут два целых числа или восемь байтов.

Вот схема, преимущество которой заключается в том, что она позволяет вам вычислить следующий хэш билета на основе предыдущего (чтобы вы могли проверить, отсутствует ли один из них), но не позволяет посторонним вычислить следующий:

Ticket.0 = substring(HASH(SALT + IV        ), 0, LENGTH)
Ticket.i = substring(HASH(SALT + Ticket.i-1), 0, LENGTH)

где

  • HASH это любая хеш-функция, которая относительно равномерно распределяет свою энтропию по выходной строке.
  • SALT это константа, которую вы держите в секрете;рекомендуется использовать разные значения для каждого события
  • IV это еще одна константа, которую ты держишь в секрете
  • ДЛИНА — это длина идентификатора билета, который вы хотите (10 в вашем вопросе, но 12 не исключено и дает вам в 256 раз больше идентификаторов билетов)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top