如何在使用 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 字符串,并且在您完成后所有的密码痕迹都会从内存中清除。