如何在使用PasswordBox时集成复杂性验证?

时间:2017-11-30 14:16:34

标签: c# .net wpf passwordbox

我有一个需要让用户创建密码的应用程序。因此,在输入密码时,需要针对密码短语测试各种规则。

这些规则非常典型 - 值必须是一定长度,有一个上面,一个下面,包含一些特殊字符等。

但是,由于这是使用PasswordBox控件的WPF应用程序,并且结果值非常敏感,如何设置复杂性比较系统,以便在用户键入时动态检查密码?

要清楚,我在密码短语创建PasswordBox元素下面的文本标签中列出了所有要求。当用户键入时,验证器会显示满足哪些要求以及哪些要求仍然需要。我还有一个熵计算器,它给出了一个典型的“好,好,强,非常强”的#34;指标一旦满足要求。这就是为什么我需要找到一种方法来安全地验证用户输入的值。

如何在不发出不安全的.Net字符串的情况下实现此目标?

1 个答案:

答案 0 :(得分:2)

如果您关心安全存储您的感知价值,您可以订阅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字符串,并且在完成后会从内存中清除每个密码的痕迹。