In WPF the Password property of a PasswordBox is not a DependencyProperty so I can't bind to it directly. As a workaround I am using this PasswordHelper from https://www.wpftutorial.net/PasswordBox.html which attaches a PasswordHelper.Password to the PasswordBox so I can bind to it.
To prevent the password from staying in the DataContext as plain text I would like to use a converter which generates a salted hash of the password before saving it to the DataContext. As I need to save both the salt and the salted hash to the DataContext I am using a MultiBinding and a IMultiValueConverter converter StringToSaltedHashConverter.
My problem is that the Password and PasswordSalt properties of my DataContext are not getting updated when I fill the PasswordBox. I have checked with Snoop and both the Password and PasswordHelper.Password properties of the PasswordBoxare changing accordingly to what I type. Also my StringToSaltedHashConverter is being called and I am returning the correct values.
I have some other bindings on this form (username, first name, last name, gender...) and they all work fine. This is the only one that is not updating.
¿Why is my DataContext not getting updated?
XAML:
<PasswordBox x:Name="Password"
Style="{DynamicResource PasswordBoxStyle1}"
local:PasswordHelper.Attach="True">
<local:PasswordHelper.Password>
<MultiBinding Converter="{StaticResource StringToSaltedHashConverter}"
Mode="OneWayToSource">
<Binding Path="Password" />
<Binding Path="PasswordSalt" />
</MultiBinding>
</local:PasswordHelper.Password>
</PasswordBox>
Code behind:
public class StringToSaltedHashConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
string str = value as string;
string salt = Hash.CreateSalt();
string hash = Hash.CreateHash(str, salt);
object[] vs = { hash, salt };
return vs;
}
}
This is not the way to go.
PasswordHelperclass and their likes should be banned from the internet. ThePasswordBox.Passwordproperty is not bindable for a very good reason which is well documented. Accessing this property will create a plain textstringrepresentation which can be effordlessly retrieved with free tools e.g. Microsoft Process Explorer.You even store the plain salt value in memory - I really hope this is neither a commercial nor a public application. You have absolutely no control when the Garbage Collector will remove any value from the memory. Since
Stringis an immutable type, it is very likely that multiple copies of the user's password will remain public in memory.Recommended authentication in a Windows environment is to use the Windows User Authentication API.
You should at least clear the
PasswordBox.Passwordproperty, by setting itnull.Encryption should not be done in the view.
And please, write responsible code! User data is not your data!
MainWindow.xaml
MainWindow.xaml.cs
ViewModel.cs
Model.cs