Безопасное использование SecureString для формы входа

Итак, этот класс, который кажется очень редко используется: SecureString. Это было примерно с 2.0 по крайней мере, и на нем есть несколько вопросов SO, но я подумал, что задаю свои конкретные вопросы:

У меня есть LoginForm; простой диалог WinForms с полями имени пользователя и (в масках) пароля. Когда пользователь вводит оба и клики "Вход", информация передается в класс введенной проверки подлинности, который выполняет слой растяжения ключа, а затем хэширует половину растянутого ключа для проверки, а другая половина - симметричный ключ для зашифрованного пользователя данные учетной записи. Когда все это закончится, loginForm будет закрыт, класс аутентификатора будет удален, и система перейдет к загрузке основной формы. Довольно стандартный материал, возможно, немного более сложный, чем стандартный хэш-пароль и сравнение, но простой хешированный пароль будет разбит в моем случае, сохранив пользовательские данные в открытом тексте, поскольку эти данные включают учетные данные для сторонних пользователей, (и все мы знаем, как люди любят повторно использовать пароли).

Вот первый вопрос; как я могу использовать SecureString для извлечения пароля из текстового поля Password, не будучи открытым как обычная System.String через свойство Text текстового поля? Я предполагаю, что есть способ получить доступ к неуправляемому окну GDI для текстового поля, которое обернуто классами CLR, и вытащить текстовые данные с использованием класса Marshal. Я просто не знаю, как, и я не могу найти хорошую информацию.

Вот второй вопрос; как только я получу пароль как SecureString, как передать его хеш-провайдеру из пространства имен System.Security.Crypto? Я предполагаю, что я буду использовать Marshal.SecureStringToBSTR(), а затем Marshal.Copy() из возвращенного IntPtr обратно в массив байтов. Затем я могу вызвать Marshal.ZeroBSTR(), чтобы очистить неуправляемую память, и я могу обнулить управляемый массив с помощью Array.Clear(), когда у меня есть хэш. Если есть более чистый способ, который позволяет мне полностью контролировать срок службы любой управляемой копии памяти, скажите.

Третий вопрос; Все это действительно необходимо или является неотъемлемой незащищенностью System.String в среде с управляемой памятью, немного раздутой? Все, что используется для хранения пароля, зашифрованного или иным образом, должно быть недоступно и на пути к сборщику мусора задолго до того, как ОС рассмотрит возможность замены приложения в виртуальную память (позволяя ему считывать пароль из файла подкачки после жесткое завершение работы компьютера). Атака с холодным ботинком - теоретическая возможность, но на самом деле, насколько это распространено? Большая озабоченность вызывает теперь расшифрованные пользовательские данные, которые зависают вокруг как часть пользователя для всего жизненного цикла приложения (и, таким образом, он будет основным кандидатом на использование SecureStrings, так как за исключением нескольких основных обычаев они остаются довольно бездействующими).

Ответ 1

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

Это нереалистичный сценарий. Не используйте SecureString. Это мало помогает и крадет ваше время.

Атаки Cold Boot более реальны, но чрезвычайно необычны. Они требуют физического доступа к машинам, который обычно полностью владеет машиной. Чтение злоумышленником является наименьшей из ваших проблем в этом случае.

В принципе, вам нужно придумать случай, когда ваше время разработки хорошо проведено с помощью SecureString.

Ответ 2

Прежде всего, я хотел бы заявить, что согласен с usr - не беспокойтесь.

Теперь к деталям:

  • Этот ответ дает большой опыт для обсуждения.
  • Это является элементом управления TextBox, который использует SecureString. Я нет использовал это, поэтому я не могу комментировать качество, но, находясь на блоге MS, я не ожидайте, что это будет что-то, кроме правильного.
  • Чтобы ответить на вопрос о передаче данных в System.Security.Crypto, в основном вы не может и никакое количество неуправляемой сортировки памяти не поможет вам, так как во время процесса сортировки строка дешифруется. Это связано с тем, что в противном случае он не может быть использован вашим целевым API. Если вы используете CSP или X509Certificate, вы можете использовать SecureSctring, потому что они поддерживаются в рамках, но об этом.