Примечание. Я изначально разместил это в Информационной безопасности, но я начинаю думать, что это может быть более актуальным здесь, поскольку оно действительно связано с определением того, что я должен делать с запрос, а не обеспечение информации.
Ситуация
Система A
:
У меня есть система A
, которая обслуживает запросы пользователей. Этот сервер что-то делает, а затем перенаправляет пользователя в систему B
. Во время этого перенаправления сервер A
может предоставить пользователю 32-значную буквенно-цифровую строку информации для передачи в систему B
. Для этого требуется 31 символ этой информации, но ее можно использовать в качестве контрольной суммы. Эта строка более или менее может считаться идентификатором запроса.
Система B
:
Когда система B
получает запрос от пользователя, он может проверить, что запрос (и строка, подобная ID) действителен, анализируя 31-символьную строку, запрашивая базу данных и разговаривая с системой A. Это система может с абсолютной уверенностью проверить, что запрос действителен и не был подделан, но он очень дорого стоит вычислить.
Нападающие:
Вероятно, эта система увидит много попыток подделать идентификатор. Это отфильтровано более поздними проверками, поэтому я не беспокоюсь о том, что один персонаж отлично подписывает идентификатор, но я не хочу тратить больше ресурсов на обработку этих запросов, чем это необходимо.
Что мне нужно
Я ищу схему контрольной суммы/подписи, которая может с одним символом дать мне хорошее представление о том, должен ли запрос продолжать процесс проверки или если он должен быть немедленно отброшен как недействительный. Если сообщение отбрасывается, я должен быть на 100% уверен, что он недействителен, но это нормально, если я сохраняю недопустимые сообщения. Я считаю, что идеальным решением будет означать, что 1/62 недействительных запросов хранится (злоумышленник должен угадать символ проверки), но в качестве минимального решения было бы отброшено половина всех недопустимых запросов.
Что я пробовал
Я рассмотрел использование алгоритма Луна (тот же, что использовался для кредитных карт), но я хотел бы иметь возможность использовать ключ для генерации персонажа, чтобы сделать его более трудным для подмены контрольной суммы. /p >
Как первая попытка создания схемы подписи, я поразрядный 31-байтовый идентификатор с 31-байтовым ключом, суммирование полученных байтов, преобразование в десятичную и добавление цифр вместе до тех пор, пока оно не станет меньше 62, затем сопоставление его с символом в наборе [a-bA-Z0-9]
(псевдокод ниже). Проблема в том, что, хотя я уверен, что это не отменит никаких действительных запросов, я не уверен, как определить, как часто это будет проходить через недопустимые идентификаторы или если ключ можно получить с помощью конечного значения.
Set alphabet to (byte[]) "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
Set keystring to "aLaklj14sdLK87kxcvalskj7asfrq01";
Create empty byte[] key;
FOR each letter in keystring
Push (index of letter in alphabet) to key;
Create empty byte[] step1;
FOR each (r, k) in (request, key)
Push r XOR s to step1;
Set step2 to 0;
FOR each b in step1
Add (int) b to step2;
WHILE step2 > 62
Copy step2 to step3;
Set step2 to 0;
Convert step3 to String;
Split step3 between characters;
FOR each digit in step3
Add (int) digit to step2;
END WHILE
RETURN alphabet[step2]
Официально
Детерминированная хеш-функция, где, учитывая закрытый ключ и вход длиной 31 байт, выводит результат в наборе {x | x ∈ ℕ, x < 62}
, где угадание результата будет более эффективным, чем вычисление закрытого ключа. (Бонусные точки для ввода переменной длины)
В конечном итоге это будет реализовано в NodeJS/JavaScript, но на самом деле не зависит от языка.
Отказ от ответственности: Прошу прощения, если этот вопрос слишком расплывчатый и теоретический. Просьба прокомментировать, если это необходимо. Есть, очевидно, способы решения этой проблемы, но в этом случае я ищу как можно более эффективное решение.