在c#dotnet核心控制台应用程序中保护密码输入

时间:2017-04-13 20:26:26

标签: c# security .net-core securestring

很长一段时间,潜伏在这里终于有了一个我没有看到的问题。我正在dotnet核心编写一个c#控制台应用程序并尝试允许用户输入密码,并担心安全性,特别是内存转储。

以下:Password masking console application我的理解是存储为字符串变量的密码可以通过内存转储公开reference)。

SecureString通常是这里的方式,但dotnet core似乎不支持。

我试图修改代码以使用char数组,因为我有限的理解是它不是不可变的,因此它不会全部存储在单个内存中。老实说虽然安全性不是我的强项,但我的问题是,如果下面的代码能够正确地保护我免于通过内存转储暴露密码吗?

        Console.WriteLine("Enter pass");
        char[] passwordArray = new char[256];
        int whileIndex = 0;

        while (true)
        {
            ConsoleKeyInfo key = Console.ReadKey(true);
            if (key.Key == ConsoleKey.Enter)
            {
                break;
            }
            else if (key.Key == ConsoleKey.Backspace)
            {
               if (whileIndex != 0) //so it doesn't explode if someone holds backspace
                {
                    whileIndex--;
                }
            }
            else
            {
                passwordArray[whileIndex] = key.KeyChar;
                whileIndex++;
            }
        }
        //Truncate array to length of password
        var endIndex = Array.IndexOf(passwordArray,'\0');
        char[] shortenedPasswordArray = new char[endIndex];
        Array.Copy(passwordArray, shortenedPasswordArray, endIndex);

        //Authentication code here

        //Wipe the characters when done
        foreach(var passChar in passwordArray)
        {
            passwordArray[passChar] = '\0';
        }

        foreach (var passChar in shortenedPasswordArray)
        {
            shortenedPasswordArray[passChar] = '\0';
        }

2 个答案:

答案 0 :(得分:2)

一些评论: 1)首先要记住,在一个应用程序中没有解决安全问题。对于完全访问机器的人来说,几乎没有任何办法可以保证密码真正安全。

(有趣的练习:如何在不将密码保存在内存中的情况下如何验证密码?)

2)SecureString只允许您确定密码何时消失,从而更好地控制内存中密码的使用寿命。普通字符串可能会在内存中持续很长时间,甚至直到程序退出,因为它在垃圾收集之前不会消失。 SecureString允许你明确地擦除它,但在此之前它仍然存在于内存中。

3)使用你自己的char数组是一个好主意,但我可能使用了List,因为它允许变量长度,甚至可能是LinkedList,因为它将字符扩展到内存中。耸肩。请参阅#1并考虑您要保护密码的攻击类型。

答案 1 :(得分:0)

在用安全密码散列算法处理后,我会存储用户的输入。当用户需要再次进行身份验证时,可以访问相同的算法,并使用结果来验证用户。