在 C# dotnet 核心控制台应用程序中保护密码输入
Securing a password input in c# dotnet core console app
在这里潜伏了很长时间终于有了一个我没有看到的问题。我正在 dotnet core 中编写一个 c# 控制台应用程序并试图允许用户输入密码,并且担心安全性,尤其是内存转储。
以下:Password masking console application my understanding is that a password stored as a string variable could be exposed through a memory dump (reference).
SecureString 通常是这里的方式,但 dotnet core 似乎不受支持。
我尝试修改代码以使用字符数组,因为我有限的理解是它不是不可变的,所以它不会全部存储在一块内存中。老实说,虽然安全不是我的强项,但我的问题是下面的代码是否正确地保护我不通过内存转储暴露密码?
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,'[=10=]');
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] = '[=10=]';
}
foreach (var passChar in shortenedPasswordArray)
{
shortenedPasswordArray[passChar] = '[=10=]';
}
一些评论:
1)首先要记住,安全不是在一个应用程序中解决的。对于拥有机器完全访问权限的人来说,(几乎)您无能为力以确保密码真正安全。
(有趣的练习:如果完全不将密码保存在内存中,您将如何验证密码?)
2) SecureString 仅让您确定密码何时消失,从而让您更好地控制密码在内存中的寿命。一个普通的字符串可能会在内存中持续很长时间,甚至直到程序退出,因为它在垃圾回收之前不会消失。 SecureString 允许您显式擦除它,但在那之前它仍然存在于内存中。
3) 使用您自己的 char 数组是个好主意,但我可能使用了 List,因为它允许可变长度,或者甚至可能使用了 LinkedList,因为它将字符分散在内存中。耸肩。回到#1 并考虑您要保护密码免受哪种攻击。
我会在安全密码哈希算法处理后存储用户的输入。当用户需要再次进行身份验证时,可以访问相同的算法,并使用结果来验证用户。
在这里潜伏了很长时间终于有了一个我没有看到的问题。我正在 dotnet core 中编写一个 c# 控制台应用程序并试图允许用户输入密码,并且担心安全性,尤其是内存转储。
以下:Password masking console application my understanding is that a password stored as a string variable could be exposed through a memory dump (reference).
SecureString 通常是这里的方式,但 dotnet core 似乎不受支持。
我尝试修改代码以使用字符数组,因为我有限的理解是它不是不可变的,所以它不会全部存储在一块内存中。老实说,虽然安全不是我的强项,但我的问题是下面的代码是否正确地保护我不通过内存转储暴露密码?
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,'[=10=]');
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] = '[=10=]';
}
foreach (var passChar in shortenedPasswordArray)
{
shortenedPasswordArray[passChar] = '[=10=]';
}
一些评论: 1)首先要记住,安全不是在一个应用程序中解决的。对于拥有机器完全访问权限的人来说,(几乎)您无能为力以确保密码真正安全。
(有趣的练习:如果完全不将密码保存在内存中,您将如何验证密码?)
2) SecureString 仅让您确定密码何时消失,从而让您更好地控制密码在内存中的寿命。一个普通的字符串可能会在内存中持续很长时间,甚至直到程序退出,因为它在垃圾回收之前不会消失。 SecureString 允许您显式擦除它,但在那之前它仍然存在于内存中。
3) 使用您自己的 char 数组是个好主意,但我可能使用了 List,因为它允许可变长度,或者甚至可能使用了 LinkedList,因为它将字符分散在内存中。耸肩。回到#1 并考虑您要保护密码免受哪种攻击。
我会在安全密码哈希算法处理后存储用户的输入。当用户需要再次进行身份验证时,可以访问相同的算法,并使用结果来验证用户。