Подтвердить что ты не робот

Внедрение безопасных уникальных URL-адресов для однократного использования в ASP.NET(С#)

У меня есть сценарий, в котором пользователям сайта, который я создаю, требуется возможность вводить некоторую базовую информацию в веб-форму без необходимости входа в систему. Сайт разрабатывается с помощью ASP.NET/C# и использует MSSQL 2005 для реляционных данных.

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

Мои запросы касаются безопасной реализации этой проблемы. Я рассматривал использование GUID как уникальный идентификатор, но не уверен в его последствиях в мире безопасности.

  • Является ли GUID достаточно длинным, чтобы значения не могли быть легко угаданы (или грубо-принудительно с течением времени)?
  • Является ли внедрение .NET GUID достаточно случайным в том смысле, что существует равная вероятность генерации всех возможных значений в "ключевом пространстве"?

  • Если использование GUID является приемлемым подходом, должен ли сайт затем перенаправляться на информацию посредством перезаписи URL-адресов или путем связывания информации в datatable с идентификатором GUID в качестве ссылки?

  • Будет ли использование перезаписи URL скрыть истинный источник данных?

  • Должен ли я использовать TSQL SELECT NEWID() в качестве генератора GUID для реализации .NET?

  • Я совершенно не согласен с моим подходом к этой проблеме?

Большое спасибо,

Карл

4b9b3361

Ответ 1

  • Да, 2 128 достаточно длинный.
  • Нет, реализация GUID предназначена для генерации GUID уникальных, а не случайных. Вы должны использовать криптографически защищенный генератор случайных чисел (например, RNGCryptoServiceProvider) для генерации 16 случайных байтов и инициализации структуры Guid с этим.
  • Да, это приемлемый подход. Оба будут работать.
  • Да, если вы не дадите никаких других подсказок
  • Нет, goto 2
  • Нет, все в порядке. Для генерации GUID вам просто нужно использовать криптографически безопасный генератор случайных чисел.

Ответ 2

  • Нет, GUID не являются полностью случайными, и большинство бит либо статичны, либо легко догадываются.
  • Нет, они не случайны, см. 1. На самом деле существует очень небольшое количество бит, которые на самом деле случайны, а не криптографически сильные случайные при этом.
  • Это не так, см. 1 и 2.
  • вы можете, но не нужно... видеть мое решение в конце.
  • Нет, см. 1 и 2
  • Да.

То, что вы должны использовать вместо GUID, является криптографически сильным генератором случайных чисел - используйте System.Security.Cryptography.RNGCryptoServiceProvider, чтобы генерировать длинные ( скажем, 32 байта) строка данных, затем base64 encode, которая.
Кроме того, если предположить, что это какая-то регистрация с конфиденциальными данными, вы хотите ограничить срок действия ссылки, скажем, 60 минут или 24 часа - зависит от вашего сайта.
Вам необходимо сохранить сопоставление этих значений определенным пользователям. Затем вы можете автоматически представить ему нужную форму по мере необходимости. Не нужно выполнять переписывание URL, просто используйте это как идентификатор пользователя (на этой странице).
Конечно, не забывайте, что этот URL должен быть HTTPS...

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

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

Ответ 3

Я бы рекомендовал просто использовать простое случайное число, например. байты из RNGCryptoServiceProvider.GetBytes. GUID не должны быть полностью случайными. Они имеют фиксированные биты, а некоторые версии используют ваш MAC-адрес. GetBytes также дает вам возможность использовать более 128 бит (хотя этого должно быть много).

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

Ответ 4

Это может быть излишним, но вы можете использовать свой адрес электронной почты SHA1, используя ваш guid (NewGuid в порядке) как хеш-соль и поместите это в URL-адрес. Затем, когда они прибудут на вашу страницу, вы можете задать им свой адрес электронной почты, получить руководство и пересчитать хеш для проверки. Даже если кто-то должен знать, какие адреса электронной почты нужно попробовать, они никогда не смогут генерировать хеш-столкновение, не зная руководства, на котором вы соленые (или это займет у них чертовски долгое время:). Конечно, вам нужно будет сохранить их электронную почту и хеш-соль guid в базе данных.

Ответ 5

Во-первых, если возможно, вы должны ограничить грубую силу, ограничив пропускную способность запроса (например, ограниченные попытки на каждый IP в секунду и ограниченные общие попытки в секунду).

В зависимости от алгоритма генерации GUID это может быть не очень хорошая идея. Хотя недавние реализации должны быть "достаточно хорошими", может быть много предсказуемости для значений. В последних реализациях, используемых в .NET, применяется хеш, иначе у вас есть четко идентифицируемые поля для MAC-адреса и время с момента загрузки. Однако возможные значения ограничены, поэтому у вас нет истинных 128 случайных бит.

Если безопасность является главным приоритетом, я бы выбрал криптографически сильный генератор случайных чисел и построил строку случайных символов. Это также делает oyu независимым от легко угадающего алгоритма (поскольку guid.ToString() легко идентифицируется как таковой), для которого атака может быть обнаружена в ближайшем будущем.

Если эти критерии выполнены, я не вижу проблемы с тем, что ключ в строке запроса.

Ответ 6

создать таблицу в базе данных с помощью linkID и столбца Datesent, при генерации ссылки send вставить DateTime.Now в таблицу и вернуть linkId, установить linkID как параметр querystring на activLink. При загрузке страницы активации извлекайте linkId и используйте его для вызова хранимой процедуры, которая вернет дату, когда передана соответствующая ссылка в качестве параметра, когда вы вернете дату, вы можете добавить, как долго вы хотите, чтобы ссылка оставалась активной на используя .AddDays()/. AddMonths - это методы С# для datetime. затем сравните дату, когда вы вернулись с сегодняшней датой. если он прошел через несколько дней или месяцев, выдаст сообщение об ошибке или продолжит просмотр содержимого страницы. Я стараюсь, чтобы вы сохраняли содержимое страницы на панели и устанавливали ее допустимым = "false", а затем делаете панель видимой = "истина", если дата все еще находится в пределах диапазона.