在C#中根据字符串生成密码

时间:2018-05-14 07:21:51

标签: c# .net asp.net-core cryptography

我想根据组织中的计算机名称生成(安全)本地管理员密码。这样我就可以构建一个小型UI,它接受计算机名并提供密码。 使用PowerShell,我们将使用相同的DLL生成密码并在每个工作站上设置它。

我已经搜索过了,但我在C#中找到的关于加密的所有内容都是哈希密码,但我需要哈希本身作为密码。

密码的长度也应介于8到12个字符之间,以便输入密码。

我正在使用.NET Core 2.0(如果需要,也可以使用.NET Framework)

2 个答案:

答案 0 :(得分:2)

您肯定希望能够更改计算机上的密码,因此在公式中包含某种日期或计数器。

理想情况下,您还希望在工具中包含某种形式的身份验证,无论是主密码,智能卡的复杂功能还是其他功能。这样,当您的工具进入坏人手中时,他们就不一定能获得您的所有数据。

如果你进入主密码路由,你需要一个如何处理被泄露的怀疑的计划。 (包括知道离开组织的人,因为那是泄密。)

一个稻草人的例子,其中包括:

  • 使用日期
  • 使用主密码
  • 使用HMAC处理机器名称,使用主密码中的密钥键入
  • 与现代计算机匹配的PBKDF2的迭代计数。

private static string GeneratePassword(
    string masterPassword,
    string machineName,
    DateTimeOffset lastChangeDate)
{
    // Use the date (ignoring time) of the last password change as a salt.
    byte[] salt = BitConverter.GetBytes(lastChangeDate.ToUniversalTime().Date.Ticks);

    HashAlgorithmName prf = HashAlgorithmName.SHA256;

    using (var pbkdf2 = new Rfc2898DeriveBytes(masterPassword, salt, 123456, prf))
    {
        byte[] key = pbkdf2.GetBytes(256 / 8);

        using (HMAC hmac = new HMACSHA256(key))
        {
            byte[] value = hmac.ComputeHash(
                Encoding.UTF8.GetBytes(machineName.ToUpperInvariant()));

            // Or however long.
            return Convert.ToBase64String(value).Substring(0, 16);
        }
    }
}

对于PBKDF2-PRF采用HashAlgorithmName的Rfc2898DeriveBytes构造函数重载是netcoreapp20中的新增功能。如果您尝试使用netstandard20,则可以删除最后一个参数并使用基于SHA-1的版本,但可能几乎没有什么危害(因为HMACSHA-1目前不被视为已损坏)。

当要更改机器的密码时,您需要输入上一代的日期才能获得现有的密码。然后输入今天的日期以获取新值,然后在任何文本文件/电子表格/数据库/便笺记下这些内容中记下新日期。

另一种方法是生成随机密码并将其保存在加密的结构化文件中。像EnvelopedCms这样的加密容器为您提供几乎免费的智能卡,并允许您在不更改所有机器密码的情况下添加/删除读取器(添加很容易,删除可能需要更改它们)。

这就是说:构建稳定的生成器并部署使用很容易。它维持它变得棘手。保持随机可能更容易,因此预先支付成本可能更好。

答案 1 :(得分:1)

我不知道这是不是一个好主意 - 只要每台计算机上的密码保持不变,该工具才有效。

无论如何,您可以散列计算机名称并将结果用作密码。大多数(如果不是全部)哈希产生的哈希值大于8-12"很容易输入"字符,但您可以通过以下方式解决:

  • Base64编码哈希(获取字母,数字和其他几个字符)
  • 从结果中获取所需数量的字符。

为了使这更安全,让你的UI获取一个密码(一个)并在计算哈希值之前将其附加到计算机名称。这样,当有人窃取您的工具时,他们仍然无法生成有效的密码。

但是,您无法更改 密码。如果您与同事共享,他们将永远知道如何重现每个密码。