【问题标题】:Phone/Tablet Style password box for WPF applicationWPF 应用程序的电话/平板电脑样式密码框
【发布时间】:2023-04-05 05:34:01
【问题描述】:

有什么方法可以使 WPF 应用程序中的PasswordBox 像大多数手机或平板电脑应用程序中使用的那样工作。也就是说,让它在短时间内以明文形式显示最后输入的字符。

【问题讨论】:

    标签: c# wpf passwords wpf-controls


    【解决方案1】:

    没有内置的方法来执行此操作,因为它违反了安全准则。请参阅此帖子以获取有关为什么不建议这样做的更多信息: How to bind to a PasswordBox in MVVM

    这是公认的答案:

    人们应该在眼睑内侧纹上以下安全准则: 切勿将纯文本密码保存在内存中。

    WPF/Silverlight PasswordBox 不为 Password 属性公开 DP 的原因与安全相关。 如果 WPF/Silverlight 要为密码保留 DP,则需要框架在内存中保持密码本身未加密。这被认为是一个相当麻烦的安全攻击媒介。 PasswordBox 使用加密内存(各种),访问密码的唯一方法是通过 CLR 属性。

    如果您仍然想实现这一点,我可以使用 TextBox 控件来实现。

    XAML:

     <TextBox Name="tbPassword"/>
    

    代码隐藏:

      string actualPassword = "";
      string displayedPassword = "";
      DispatcherTimer dispatcherTimer = new DispatcherTimer();
    
      public MainWindow()
      {
         InitializeComponent();
         tbPassword.PreviewKeyDown += tbPassword_PreviewKeyDown;
         tbPassword.PreviewTextInput += tbPassword_PreviewTextInput;
    
         dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
         dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
      }
    
      private void tbPassword_PreviewKeyDown(object sender, KeyEventArgs e)
      {
         if (e.Key == Key.Back)
         {
            if (actualPassword.Length > 0)
            {
               actualPassword = actualPassword.Substring(0, actualPassword.Length - 1);
               if (actualPassword.Length > 0)
               {
                  ShowLastCharacter();
                  tbPassword.CaretIndex = displayedPassword.Length;
               }
            }
         }
      }
    
      private void tbPassword_PreviewTextInput(object sender, TextCompositionEventArgs e)
      {
         actualPassword += e.Text;
         e.Handled = true;
         ShowLastCharacter();
         tbPassword.CaretIndex = displayedPassword.Length;
      }
    
    
      private void ShowLastCharacter()
      {
         var lastChar = actualPassword.Substring(actualPassword.Length - 1);
         displayedPassword = "";
         for (int i = 0; i < actualPassword.Length - 1; i++)
            displayedPassword += "•";
         displayedPassword += lastChar;
         tbPassword.Text = displayedPassword;
    
         if (dispatcherTimer.IsEnabled)
            dispatcherTimer.Stop();
    
         dispatcherTimer.Start();
      }
    
      private void dispatcherTimer_Tick(object sender, EventArgs e)
      {
         displayedPassword = "";
         for (int i = 0; i < actualPassword.Length; i++)
            displayedPassword += "•";
    
         tbPassword.Text = displayedPassword;
         tbPassword.CaretIndex = displayedPassword.Length;
      }
    

    【讨论】:

    • 我看到那篇关于通用数据绑定的文章,并怀疑这可能是我找不到启用它的内置选项的原因。在我的例子中,客户希望向其最终用户提供一个简短的数字密码作为“荣誉系统”的替代方案,以替代更安全的身份验证选项(例如智能卡)。假设他们坚持要包含它,那么即使使用慢速哈希存储,一个足够小的密钥空间也可以简单地进行暴力破解,这是一个如此大的开口,它可以说是微不足道的这种内存攻击。 叹息
    猜你喜欢
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    相关资源
    最近更新 更多