SecureString для хранения в памяти и представления паролей? Или что-то другое? - PullRequest
10 голосов
/ 26 июня 2011

Я написал небольшую программу для себя, используя C #, которую я могу использовать для хранения своих паролей, а затем извлекать их для просмотра / редактирования.

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

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

Есть ли более безопасный способ сделать это, чем использование класса SecureString, или SecureString соответствует его названию?

Ответы [ 4 ]

11 голосов
/ 26 июня 2011

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

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

8 голосов
/ 03 января 2012

SecureString каким-то образом защищает экземпляр строки в памяти, однако вы должны знать о некоторых существенных недостатках.

  • SecureString (как указывает svick) можно получить безключ дешифрования, поэтому любой хакер, достаточно опытный для извлечения этого фрагмента памяти, который вы можете с уверенностью предположить, может легко выполнить эту незначительную операцию для получения строки в виде простого текста.Рассмотрим простоту SecureStringToBSTR(input);
  • SecureString необходимо заполнять символьно-символьным способом, так как нет свойства .Text для использования метода доступа Get или Set.В блогах, включая MSDN, вы часто видите код, подобный следующему:

    public static SecureString StringToSecureString(string input)
    {
        SecureString output = new SecureString();
        int l = input.Length;
        char[] s = input.ToCharArray(0, l);
        foreach (char c in s)
        {
            output.AppendChar(c);
        }
        return output;
    }
    

Существенная проблема этого кода заключается в том, что разработчик разрешил строке input ever существует в памяти в первую очередь.Пользовательский элемент управления или WinForm TextBox для PasswordBox, используемый для сбора этого пароля от пользователя, никогда не должен собирать весь пароль за одну операцию, так как

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

Вместо этого рассмотрите варианты, в которых KeyPress используется для получения каждого символа от пользователя, в противном случаеЯ полагаю, что PasswordBox WPF по умолчанию поддерживается SecureString (кто-то другой может это подтвердить).

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

1 голос
/ 26 июня 2011

SecureString в точности соответствует названию, и вы уже догадались: он сохраняет строку, также зашифрованную в памяти, так что да, это правильный путь.
См. ЗДЕСЬ :

Представляет текст, который должен быть конфиденциальным.Текст зашифрован для конфиденциальности при использовании и удален из памяти компьютера, когда он больше не нужен.Этот класс не может быть унаследован.

0 голосов
/ 09 июня 2016

Вы, ребята, делаете этот путь слишком сложным.Никто не спросил, был ли это лучший способ решить проблему.Они просто хотят увидеть какой-то рабочий код.Jeez.В этом примере passwordPre - это строка, которая была расшифрована из ресурса (например, из файла конфигурации) с использованием вашего собственного алгоритма дешифрования.

    string passwordPre = DecryptProprietary(objectReferringToPassword);
    char[] passwordChars = passwordPre.ToCharArray();        
    System.Security.SecureString securePassword = new System.Security.SecureString(); // in production, this should probably be a global variable
    foreach (char c in passwordChars)
        securePassword.AppendChar(c);

    string decryptedPassword = new System.Net.NetworkCredential(string.Empty, securePassword).Password; // this is how to convert it to a string for quick usage to access the protected resource

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...