Какой "хороший" алгоритм шифрования блоков имеет самый короткий результат?

Я хотел бы предоставить клиентам случайный номер заказа, но использовать 0, 1, 2,... в бэкэнд. Таким образом, клиент получает URL-адрес статуса заказа, не защищенного паролем, с зашифрованным номером заказа, и они не могут смотреть на номера заказов других клиентов путем добавления или вычитания 1. Это может заменить схему, в которой генерируются случайные ключи заказа, проверяется на уникальность среди всех предыдущих заказов, и сгенерирован до уникального. Когда веб-сервер получает запрос на просмотр заказа, он расшифровывает номер заказа и получает заказ.

Чтобы сохранить короткий URL, какой "хороший" алгоритм шифрования имеет самый короткий размер блока? Является ли эта схема хорошей идеей? (Что делать, если я шифровал идентификаторы сотрудников Apple, Inc., чтобы Стив Смит не попросил сотрудника № 0?)

Обратите внимание, что все веб-сайты отслеживания пакетов позволяют отслеживать пакеты без проверки подлинности. Было бы неплохо ограничить объем информации, отображаемой на странице состояния заказа без пароля.

Ответы

Ответ 1

Большинство блочных шифров будут использовать блоки размером более 32 бит по соображениям безопасности.

Однако я нашел тот, который сделан специально для того, что вы делаете: Skip32

Вы можете использовать GUID, но, возможно, у вас есть причины, по которым вы хотите этого избежать. (Скажем, ваше приложение уже сделано.)

Изменить: На самом деле, если GUID допустим, то это дает вам диапазон 128 бит. Вы можете легко использовать любой другой блок-шифр. Преимущество использования большего пространства (за счет длинных строк ID) заключается в том, что у вас будет гораздо больше защиты от людей, угадывающих идентификаторы. (Не то, чтобы это идентификатор заказа сам по себе должен быть маркером безопасности в любом случае...)

Ответ 2

Если ваша идея состоит в том, что достаточно знать номер заказа (или URL), чтобы получить информацию о заказе, выполните следующие действия:

  • Пространство номеров заказов должно быть очень большим, в противном случае злоумышленники и/или клиенты будут, по-видимому, искать пространство порядка, чтобы увидеть, что можно увидеть.
  • Вы должны учитывать, что злоумышленник может начать постепенное зондирование с многочисленных машин и может быть терпеливым.
  • Проверка пространства номера заказа может быть уменьшена с помощью ограничения скорости, но это очень сложно применить в веб-среде - трудно отличить доступ вашего клиента от доступа злоумышленника.
  • Считайте также, что номер заказа не является секретом, люди могут отправлять его по электронной почте; после этого невозможно отказаться.

Итак, для удобства однократного check-my-order-without-logging-in вы создали постоянный риск для безопасности.

Даже если вы сделаете номер номера заказа огромным, у вас все еще есть проблема, что эти URL-адреса плавают вокруг, возможно, владеют людьми, которые не должны их получать.

Было бы намного лучше потребовать сеанс входа в систему, чтобы что-то увидеть, а затем показывать только те заказы, которые им разрешено видеть. Тогда вам не нужно беспокоиться о том, чтобы скрывать номера заказов или злоумышленников, угадывая номера заказов, потому что просто номер заказа недостаточно информации для доступа к чему-либо.

Ответ 3

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

Ответ 4

Вопросы о том, следует ли вам на самом деле делать это в стороне, вот очень простой блочный шифр с фиксированным ключом (так как вам все равно нужна одна перестановка).

static uint permute(uint id)
{
  uint R = id & 0xFFFF, L = (id>>16) ^ (((((R>>5)^(R<<2)) + ((R>>3)^(R<<4))) ^ ((R^0x79b9) + R)) & 0xFFFF);
  R ^= ((((L>>5)^(L<<2)) + ((L>>3)^(L<<4))) ^ ((L^0xf372) + L)) & 0xFFFF;
  return ((L ^ ((((R>>5)^(R<<2)) + ((R>>3)^(R<<4))) ^ ((R^0x6d2b) + R))) << 16) | R;
}

Skip32 намного лучше, чем 32-битные блок-шифры, но он немного тяжеловес, когда будут выполняться три (длинные) строки.: -)

Ответ 5

Недавно я начал использовать Hashids набор небольших библиотек. Идея состоит в том, чтобы зашифровать число или список чисел в хешированную строку, например:

12345 => "NkK9"
[683, 94108, 123, 5] => "aBMswoO2UB3Sj"

Библиотеки реализуются на популярных языках программирования различными авторами. Они также являются кросс-совместимыми, что означает, что вы можете кодировать число в Python, а затем декодировать его JavaScript. Он поддерживает определение солей, алфавита и даже исключение плохих слов.

Python:

hashids = Hashids(salt="this is my salt")
id = hashids.encode(683, 94108, 123, 5)

JS:

var hashids = new Hashids("this is my salt"),
numbers = hashids.decode("aBMswoO2UB3Sj");

Это не шифрование govt proof, но вполне достаточное для некоторых сайтов, не предсказуемых для передачи по ссылке.

Ответ 7

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

Если вы ДЕЙСТВИТЕЛЬНО хотите просто иметь все заказы там без какой-либо проверки подлинности, GUID будет лучше.

Или вы могли бы попытаться придумать порядковые номера с префиксом чего-то о клиенте. Like (PhoneNumber) (1... 100)

Ответ 8

Чтобы удовлетворить требование, вы можете просто использовать хэш, например SHA-1 или MD5 в ваших индексах. Они обеспечат необходимую безопасность.

Чтобы уменьшить размер, вы можете изменить его на другую кодировку; например 64 бит.

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