【问题标题】:Securing a password input in c# dotnet core console app在 c# dotnet core 控制台应用程序中保护密码输入
【发布时间】:2017-09-10 02:24:02
【问题描述】:

在这里潜伏了很久终于有一个我没有看到的问题。我正在 dotnet core 中编写一个 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';
        }

【问题讨论】:

  • AFAIK 数组仍然会被分配连续的内存空间,
  • 您的威胁模型是什么?谁在做什么?
  • @NeilMcGuigan 不确定该上下文有多大帮助。此应用程序的目的是运行 LDAP 查询以下拉 AD 对象列表,并且我请求用户/通行证绑定连接。虽然我个人认为它比保存凭据/在设备之间传递它们的风险更低,但它可能由具有有价值凭据的 IT 管理员执行,所以我想在这里做我的尽职调查。
  • 谁会进行攻击?他们在哪里?
  • @NeilMcGuigan 如果我从另一个方向开始说这个可能会更容易。如果这是一个 .NET Standard 应用程序,我会在这里使用 SecureString 并称之为一天,所以我们可以将其重新表述为:上面的代码引入了多少额外的风险而不是使用 SecureString?据我所知,最大的区别是 SecureString 在内存中加密,这使得它更能防止内存转储。我离开这里了吗?如果不重新创建 SecureString,这种风险是否不可避免?

标签: c# security .net-core securestring


【解决方案1】:

一些cmets: 1)首先要记住,安全性不是在一个应用程序中解决的。对于可以完全访问机器的人来说,您(几乎)无法采取任何措施来确保密码真正安全。

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

2) SecureString 仅通过让您确定密码何时消失,让您更好地控制密码在内存中的使用寿命。一个普通的字符串可能会在内存中持续很长时间,甚至直到程序退出,因为它直到垃圾回收才会消失。 SecureString 可让您显式擦除它,但在此之前它仍然存在于内存中。

3) 使用您自己的 char 数组是个好主意,但我可能使用了 List,因为它允许可变长度,甚至可能使用 LinkedList,因为它将字符分散在内存中。耸耸肩。请参考 #1 并考虑您要保护密码免受哪种攻击。

【讨论】:

  • 第一段是关键。您可以识别的任何需要攻击者对运行程序的机器进行不受限制的物理访问的漏洞都不是您作为程序员应该担心的漏洞。这不是代码或数据安全问题;这是一个物理安全问题。所谓的“白盒安全”,即攻击者可以监视计算机所做的一切但仍然无法破解安全的想法,被认为是困难的,并且被一些人认为是不可能的。
  • 欣赏这个答案和评论。我意识到我担心的情况可能涉及一台受到严重破坏的计算机,没有任何东西可以挽救它。安全性只是我非常新手的一个巨大的野兽,并且主要想健全检查我没有做一些“密码贴在显示器上”相当于这里的编码。谢谢。
  • 我曾经在微软工作过。他们有一个政策,只有安全团队中的人被允许从事安全工作,因为计算机安全中有很多陷阱,未经培训的人很可能会制造灾难性的后门。不懂领域也不要难过,问问题也很好。
【解决方案2】:

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

【讨论】:

  • Windows 已验证可用的哈希算法,但这并不更安全,因为您仍需要内存中的哈希码。
  • 是的,你是对的。散列算法需要一个参数,它只是指向内存中的一个位置。我不确定如何保护应用程序的内存,除非整个内存空间都受到某种加密层的保护,所有存储的数据在到达内存之前都会被加密。
  • 也许你可以存储一个你比较输入的密钥文件。我真的不明白你怎么能阻止用户的输入到达记忆。我看到的唯一其他选择是使用某种类型的身份验证器来连接移动设备,或者您可以只在机器上存储一些 SSH 密钥。但是到那时,任何具有管理员权限的恶意程序或用户都可以访问您的 SSH 密钥。这是人事问题,不是软件问题。
  • 实际上操作系统确实保护内存。一个程序不可能访问另一个程序的内存,除非它已被授予重要权限,如果您授予程序此类权限,那么这就是您真正的安全漏洞所在。
猜你喜欢
  • 2017-03-14
  • 2011-04-09
  • 2018-02-16
  • 2013-11-10
  • 2019-10-09
  • 1970-01-01
  • 2018-02-09
  • 2018-01-16
  • 1970-01-01
相关资源
最近更新 更多