Привязка PasswordBox к SecureString и его сериализация UWP

307
22 февраля 2018, 11:19

Появился следующий вопрос: можно ли каким-то образом привязать PasswordBox к SecureString, следующим образом:

SecureString Password { get; set; }
...
<PasswordBox Password="{x:Bind Password, Mode=TwoWay}" />

Или же необходимо реализовывать метод добавления нового символа к строке с паролем? При этом нужно как то сериализовать объект SecureString, который не поддается Json сериализации. Как можно решить данные проблемы?

Answer 1

Я не специалист по ИБ, но весь смысл SecureString как раз и состоит в том, что строка с паролем не хранится в памяти в явном виде, а вы ее еще и по сети хотите отправлять (или что вы там будете с json делать).

Вот вам один из способов реализации привязки из WPF (в UWP должно отличаться не сильно, проверить сейчас не могу):

public class BindablePasswordBox : Decorator
{
    public static readonly DependencyProperty PasswordProperty
        = DependencyProperty.Register(nameof(Password), typeof(string), typeof(BindablePasswordBox),
            new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnPasswordPropertyChanged));
    static void OnPasswordPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs eventArgs)
    {
        var bpb = (BindablePasswordBox)d;
        if (bpb.isPreventCallback) return;
        bpb.passwordBox.PasswordChanged -= bpb.HandlePasswordChanged;
        bpb.passwordBox.Password = (string)eventArgs.NewValue;
        bpb.passwordBox.PasswordChanged += bpb.HandlePasswordChanged;
    }
    bool isPreventCallback = false;
    PasswordBox passwordBox = new PasswordBox { PasswordChar = '*' };
    public BindablePasswordBox()
    {
        passwordBox.PasswordChanged += HandlePasswordChanged;
        Child = passwordBox;
    }
    public string Password
    {
        get => (string)GetValue(PasswordProperty);
        set => SetValue(PasswordProperty, value);
    }
    void HandlePasswordChanged(object sender, RoutedEventArgs eventArgs)
    {
        isPreventCallback = true;
        Password = passwordBox.Password;
        isPreventCallback = false;
    }
}

Теперь, можно использовать BindablePasswordBox вместо PasswordBox:

<cntrl:BindablePasswordBox Password="{Binding MyPassword}"/>

Где cntrl - это пространство имен класса cntrl:BindablePasswordBox

READ ALSO
Библиотека xceedsoftware/DocX

Библиотека xceedsoftware/DocX

Здравствуйте,работаю с библиотекой xceedsoftware для формирования графиков в вордеПодскажите пожалуйста как добавить подписи к данным?пример...

236
Как использовать локальную базу данных?

Как использовать локальную базу данных?

Создаю проект, формы и всю реализациюВ каждой форме по коннект-строке и эта строка такая:

247
Как сделать cast с помощью переменной типа Type?

Как сделать cast с помощью переменной типа Type?

Допустим где-то ранее по коду я сохранил тип переменной

241
Проблема с классом Random в C# [дубликат]

Проблема с классом Random в C# [дубликат]

На данный вопрос уже ответили:

326