Управление жизненным циклом SqlCredential и SecureString

#.net #sql-server #authentication #securestring

#.net #sql-сервер #аутентификация #securestring

Вопрос:

System.Data.SqlClient.SqlCredential Класс имеет конструктор с двумя аргументами, который принимает имя пользователя ( System.String ) и пароль ( System.Security.SecureString ).

Безопасно ли после вызова этого конструктора удалять SecureString сохранение пароля? Я ожидаю, что SqlCredential класс должен выполнить односторонний хэш для пароля в соответствии со схемой аутентификации SQL Server и не требовать постоянного доступа к параметру… но, возможно, это невозможно сделать, пока соединение не будет открыто и не будет выдан вызов (одноразовый номер может быть задействован в вычислении HMAC для предотвращения повторных атак). Если SqlCredential независимо сохраняет необходимую информацию, то, естественно, я хочу ускорить удаление SecureString хранилища, которое является обратимым.

Мне не удалось найти в документации какое-либо утверждение, указывающее SecureString , должен ли переданный объект password оставаться действительным после SqlCredential возврата конструктора.

Комментарии:

1. в ссылке на github src github.com/dotnet/corefx/blob/master/src/System.Data.SqlClient /… он присваивается закрытому полю после проверки, установлено ли для него значение Только для чтения. Из docs.microsoft.com/en-us/dotnet/api /… есть указание на неизменяемое поведение после того, как оно сделано доступным только для чтения. Но было бы неплохо получить некоторое представление и ясность в этом вопросе.

2. на самом деле.. Возможно, я неправильно истолковал документ, исходя из предпосылки неизменности в отношении создания новых экземпляров. На самом деле, я думаю, что документ указывает, что он не будет создавать новые экземпляры — поэтому вам, вероятно, не следует его утилизировать и ожидать, что экземпляр SqlCredentials будет работать независимо … вероятно, вы можете подтвердить это с помощью быстрого теста в любом случае

3. @BrettCaswell: О, я определенно вызываю ObjectDisposedException , если я удаляю пароль. Но я не думаю, что так оно и должно работать. Предполагается, что SecureString должен быть удален, когда он больше не нужен, и если я не могу его удалить (потому что я делюсь экземпляром с SqlCredential ) и SqlCredential не могу его удалить (потому что он делится со мной), тогда конфиденциальные данные будут оставаться до тех пор, пока сборщик мусора не решит вызвать финализатор, который окончательно обнуляет егоотсутствует.

4. вероятно, это еще одна причина, по которой его не рекомендуется использовать. а также для того, чтобы избежать учетных данных. github.com/dotnet/platform-compat/blob/master/docs / … .. но, я думаю, вы можете дать ответ на этот вопрос, заметив, что это исключение возникает после удаления. Похоже, это соответствует документам, поскольку относится к SecureString, имеющему один экземпляр.

Ответ №1:

SqlCredential на самом деле не обрабатывает и не хранит какие-либо данные, полученные из паролей; это просто удобная структура для хранения параметров, связанных с учетными данными, связанных с SqlConnection .

Экземпляр пароля SecureString должен оставаться действительным до тех пор, пока вызов SqlConnection.Open() или эта функция не выдаст ObjectDisposedException . Если, как и у меня, в вашем приложении есть какая-либо логика автоматического повторного подключения, вам нужно будет сохранить SecureString (или возможность ее повторного создания) на неопределенный срок. По крайней мере, в .NET Framework с Win32 SecureString его содержимое шифруется в состоянии покоя, поэтому дамп памяти процесса не раскрывает секрет.