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

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

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

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


person joeforker    schedule 04.02.2009    source источник
comment
Почему? Вам не кажется, что UUID или Глобальный уникальный идентификатор подойдет для этого лучше всего? Для этого есть библиотеки.   -  person Johannes Weiss    schedule 04.02.2009
comment
Немного странно, что вы поставили статус заказа за незащищенной паролем ссылкой. Безопасность по неясности вообще не очень хорошая безопасность.   -  person Chaos    schedule 24.08.2014


Ответы (8)


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

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

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

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

person MichaelGG    schedule 04.02.2009
comment
Спасибо. Если бы длина URL-адреса не была проблемой, то, если бы мне нужно было избежать AUTO INCREMENT, я бы использовал GUID, а если бы последовательные идентификаторы за кулисами были в порядке, я бы использовал AES. В отличие от GUID, AES позволяет мне не хранить длинные идентификаторы в уникальном индексе для каждого заказа. - person joeforker; 05.02.2009
comment
Хороший ответ. Для полноты я упомяну, что использование порядкового номера в открытом тексте и добавление N бит HMAC с ключом было бы другой альтернативой и, возможно, более простой в зависимости от того, что у вас есть под рукой. - person Liudvikas Bukys; 05.02.2009
comment
@Liudvikas: сокрытие номера заказа является одним из основных моментов этого упражнения, чтобы клиент не мог догадаться, насколько мы маленькая компания, по тому, как медленно увеличиваются наши номера заказов. - person joeforker; 05.02.2009

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

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

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

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

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

person Liudvikas Bukys    schedule 04.02.2009
comment
Хорошие моменты, но это не должно иметь большого значения, если злоумышленник знает, отправлен ли чей-то заказ или нет (вместо этого они могут атаковать UPS). Ссылка для заказа без пароля может быть спроектирована так, чтобы не отображать ценные секреты. - person joeforker; 05.02.2009

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

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

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

Питон:

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");

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

person gertas    schedule 05.04.2015

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

person joeforker    schedule 04.02.2009
comment
Я тоже подумал о рыбке. Любые ссылки? - person Chibueze Opata; 09.09.2018

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

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-битных блочных шифров, но он немного тяжеловесен, когда достаточно трех (длинных) строк. :-)

person Adam M.    schedule 15.03.2012
comment
У него есть имя или наследие? - person joeforker; 15.03.2012
comment
Этот? Не совсем. Я придумал это, прочитав о сетях Фейстеля. Я назвал его syfer в своем коде, и эта версия также принимала 32-битный ключ. (Эта версия здесь.) Некоторые константы могли быть заимствованы или адаптированы из XXTEA, хотя я точно не помню. Я использую его для генерации перестановок целых чисел. Не рекомендую из соображений безопасности. - person Adam M.; 29.10.2013

guid - это путь к этому

* изменить *

вы можете посмотреть на этот http://csharpfeeds.com/post/4382/A_shorter_and_URL_friendly_GUID.aspx

person Fredou    schedule 04.02.2009

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

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

Или вы можете попытаться придумать номера заказов с префиксом что-то о покупателе. Нравится (номер телефона)(1...100)

person Bob    schedule 04.02.2009
comment
Таким образом, вы можете отслеживать посылки FedEx и UPS. - person joeforker; 04.02.2009
comment
Я подумал, что (SocialSecurityNumber)(1...100) может подойти. :-) - person joeforker; 04.02.2009
comment
@joe - лол, вау, SSN! Звучит как запись для ежедневного wtf - person Gavin Miller; 04.02.2009

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

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

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

person Gavin Miller    schedule 04.02.2009
comment
@Michael - вам не хватает одного из требований вопроса, а именно использования линейной индексации. - person Gavin Miller; 04.02.2009
comment
С таким названием я разочарован тем, что вы не предложили что-то основанное на сдвиговом регистре с линейной обратной связью. - person joeforker; 04.02.2009
comment
@LFSR - я не видел требований к линейной индексации. Он сказал, что ему нужны натуральные числа в бэкенде и случайные во внешнем интерфейсе. Шифровальный блок подходит идеально. Хэш - нет, так как он не уникален. - person MichaelGG; 04.02.2009
comment
@Michael - Извините, я что-то упустил. Это уникальный номер заказа с хэшем? Как это не будет уникальным? - person Gavin Miller; 04.02.2009
comment
Хэши не обязательно будут уникальными для любого ввода, вот почему. Итак, в данном случае он выполняет H(SALT + ID). Ему пришлось бы предварительно вычислять и проверять каждый идентификатор, чтобы убедиться, что он уникален. (Конечно, SHA1 с более чем несколькими тысячами идентификаторов заказов вероятно будет в порядке, но ему придется доказывать это вручную.) - person MichaelGG; 04.02.2009
comment
О, я также должен отметить, что если вы предоставляете хэш только в URL-адресах, это означает, что вам нужно вычислить и сохранить хэш, поскольку вы не можете отменить его, кроме как с помощью грубой силы. - person MichaelGG; 04.02.2009
comment
Смелые программисты доверяют хэш-коду, это невероятно маленький риск с SHA1 и его аналогами. Например, git хранит каждую ревизию каждого файла по хешу и работает нормально. Для этого вопроса, если бы мне нужно было как минимум 128 бит, я бы использовал AES. Сложность заключается в коротком URL-адресе. - person joeforker; 04.02.2009