如何在使用 PasswordBox 时集成复杂性验证?
How can I integrate complexity verification while using a PasswordBox?
我有一个需要让用户创建密码的应用程序。因此,在输入密码时需要根据各种规则对其进行测试。
这些规则很典型——值必须有一定的长度,有一个大,一个小,包括一些特殊字符等。
但是,由于这是一个使用 PasswordBox
控件的 WPF 应用程序,并且结果值非常敏感,我如何设置复杂性比较系统以在用户输入时动态检查密码?
为了清楚起见,我在密码短语创建 PasswordBox 元素下方的文本标签中列出了所有要求。当用户键入时,验证器会显示满足哪些要求以及仍需要哪些要求。我还有一个熵计算器,一旦满足要求,它就会给出一个典型的 "OK, Good, Strong, Very Strong" 指标。这就是为什么我需要找到一种方法来在用户输入时安全地验证值。
如何在不发出不安全的 .Net 字符串的情况下完成此操作?
您可以订阅 PasswordChanged
,但如果您关心安全地存储您的感知价值,请不要使用 Password
属性。相反,这样做:
private void OnPasswordChanged(object sender, RoutedEventArgs e) {
using (var pwd = ((PasswordBox) sender).SecurePassword) {
int length = pwd.Length;
if (length == 0) {
// string empty, do something
return;
}
bool hasSpecial = false;
bool hasUpper = false;
bool hasLower = false;
bool hasDigit = false;
// etc
// allocate unmanaged memory and copy string there
IntPtr ptr = Marshal.SecureStringToBSTR(pwd);
try {
// each char in that string is 2 bytes, not one (it's UTF-16 string)
for (int i = 0; i < length * 2; i += 2) {
// so use ReadInt16 and convert resulting "short" to char
var ch = Convert.ToChar(Marshal.ReadInt16(ptr + i));
// run your checks
hasSpecial |= IsSpecialChar(ch);
hasUpper |= Char.IsUpper(ch);
hasLower |= Char.IsLower(ch);
hasDigit |= Char.IsDigit(ch);
}
}
finally {
// don't forget to zero memory to remove password from it
Marshal.ZeroFreeBSTR(ptr);
}
}
}
这样您就不会在验证期间构建 .NET 字符串,并且在您完成后所有的密码痕迹都会从内存中清除。
我有一个需要让用户创建密码的应用程序。因此,在输入密码时需要根据各种规则对其进行测试。
这些规则很典型——值必须有一定的长度,有一个大,一个小,包括一些特殊字符等。
但是,由于这是一个使用 PasswordBox
控件的 WPF 应用程序,并且结果值非常敏感,我如何设置复杂性比较系统以在用户输入时动态检查密码?
为了清楚起见,我在密码短语创建 PasswordBox 元素下方的文本标签中列出了所有要求。当用户键入时,验证器会显示满足哪些要求以及仍需要哪些要求。我还有一个熵计算器,一旦满足要求,它就会给出一个典型的 "OK, Good, Strong, Very Strong" 指标。这就是为什么我需要找到一种方法来在用户输入时安全地验证值。
如何在不发出不安全的 .Net 字符串的情况下完成此操作?
您可以订阅 PasswordChanged
,但如果您关心安全地存储您的感知价值,请不要使用 Password
属性。相反,这样做:
private void OnPasswordChanged(object sender, RoutedEventArgs e) {
using (var pwd = ((PasswordBox) sender).SecurePassword) {
int length = pwd.Length;
if (length == 0) {
// string empty, do something
return;
}
bool hasSpecial = false;
bool hasUpper = false;
bool hasLower = false;
bool hasDigit = false;
// etc
// allocate unmanaged memory and copy string there
IntPtr ptr = Marshal.SecureStringToBSTR(pwd);
try {
// each char in that string is 2 bytes, not one (it's UTF-16 string)
for (int i = 0; i < length * 2; i += 2) {
// so use ReadInt16 and convert resulting "short" to char
var ch = Convert.ToChar(Marshal.ReadInt16(ptr + i));
// run your checks
hasSpecial |= IsSpecialChar(ch);
hasUpper |= Char.IsUpper(ch);
hasLower |= Char.IsLower(ch);
hasDigit |= Char.IsDigit(ch);
}
}
finally {
// don't forget to zero memory to remove password from it
Marshal.ZeroFreeBSTR(ptr);
}
}
}
这样您就不会在验证期间构建 .NET 字符串,并且在您完成后所有的密码痕迹都会从内存中清除。