【问题标题】:How to get password as SecureString from DevExpress WinForms TextEdit如何从 DevExpress WinForms TextEdit 获取密码作为 SecureString
【发布时间】:2011-02-01 05:49:38
【问题描述】:

WPF 有 PasswordBox,它接收密码输入到 SecureString,但我有一个 WinForms 应用程序。我可以使用SecurePasswordTextBox,但我想要一些与 DevExpress 控件和 DevExpress 外观定制相结合的东西。在 DevExpress TextEdit 控件上,您可以设置 UseSystemPasswordChar = true,但它不使用 SecureString(也不会:cf. 10/22/2010cf. also

如何在 DevExpress WinForms TextEdit 控件中轻松获得 SecureString 支持?

我想出了一些东西,我将其发布在下面作为我自己的答案。其他人有解决方案吗?

编辑:我接受我自己的答案,这是可行的,因为我需要 DevExpress 的外观。

【问题讨论】:

    标签: winforms security devexpress


    【解决方案1】:

    这是我自己的答案:

    我没有将 TextEdit 子类化,这似乎太复杂了,我只是捕获 KeyPress 事件并将每个按下的字符隐藏起来,直到 EditValueChanging 事件。我将唯一标记保存在一个假字符串中,这样我就可以在每个 EditValueChanging 事件中找出我的 SecureString 中要更改的内容。

    这是概念验证——一个带有 TextEdit 控件和两个事件处理程序的简单表单:

    public partial class PasswordForm : DevExpress.XtraEditors.XtraForm
    {
        private Random random = new Random();
        private HashSet<char> pool = new HashSet<char>();
        private char secret;
        private char token;
        private List<char> fake = new List<char>();
    
        public PasswordForm()
        {
            InitializeComponent();
            this.Password = new SecureString();
            for (int i = 0; i < 128; i++)
            {
                this.pool.Add((char)(' ' + i));
            }
        }
    
        public SecureString Password { get; private set; }
    
        private void textEditPassword_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
        {
            string value = e.NewValue as string;
    
            // If any characters have been deleted...
            foreach (char c in this.fake.ToArray())
            {
                if (value.IndexOf(c) == -1)
                {
                    this.Password.RemoveAt(this.fake.IndexOf(c));
                    this.fake.Remove(c);
                    this.pool.Add(c);
                }
            }
    
            // If a character is being added...
            if (this.token != '\0')
            {
                int i = value.IndexOf(this.token);
                this.Password.InsertAt(i, this.secret);
                this.secret = '\0';
                fake.Insert(i, this.token);
            }
        }
    
        private void textEditPassword_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (Char.IsControl(e.KeyChar))
            {
                this.token = '\0';
            }
            else
            {
                this.token = this.pool.ElementAt(random.Next(this.pool.Count)); // throws ArgumentOutOfRangeException when pool is empty
                this.pool.Remove(this.token);
                this.secret = e.KeyChar;
                e.KeyChar = this.token;
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      最简单的方法是使用托管在 ElementHost 中的 WPF PasswordBox。

      您可以从 ToolBox 中拖动 ElementHost 控件,或者在代码中完成所有操作:

      public Form1()
      {
          InitializeComponent();
          System.Windows.Forms.Integration.ElementHost host = new System.Windows.Forms.Integration.ElementHost();
          System.Windows.Controls.PasswordBox pb=new System.Windows.Controls.PasswordBox();
          host.Child =  pb;
          this.Controls.Add(host);
      }
      

      当然这不使用 DevExpress 控件,但是当有一个简单的替代方案时,我看不出有任何理由使用富文本编辑器作为密码框。

      【讨论】:

      • 这很容易,尽管我失去了 DevExpress 的外观行为。我会试试看它看起来如何。我使用的是 DevExpress.XtraEditors.TextEdit,它是一个简单的单行编辑器,不是富文本,但拥有开箱即用的 SecureString 功能会更好。
      • 抱歉,我没有意识到您想要保留的是 DevExpress 样式。
      猜你喜欢
      • 2012-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多