【问题标题】:Extracting/Decrypting hashed/salted password out of XML file从 XML 文件中提取/解密散列/加盐密码
【发布时间】:2014-02-20 14:48:56
【问题描述】:

我在本节目中读到的大部分主题都是将密码与散列/加盐密码进行比较。那不是我的用例。我需要从 xml 文件中读取散列/加盐密码,然后使用它登录 Sql 数据库。我需要从 Windows 服务中执行此操作。我首先不确定如何读取 XML 文件中的该条目,然后如何“解密”它?

GenerateSaltForPassword 和 ComputePasswordHash 函数直接来自This SO post

private int GenerateSaltForPassword()
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] saltBytes = new byte[4];
            rng.GetNonZeroBytes(saltBytes);
            return (((int) saltBytes[0]) << 24) + (((int) saltBytes[1]) << 16) + (((int) saltBytes[2]) << 8) +
                   ((int) saltBytes[3]);
        }

        private byte[] ComputePasswordHash(string password, int salt)
        {
            byte[] saltBytes = new byte[4];
            saltBytes[0] = (byte) (salt >> 24);
            saltBytes[1] = (byte) (salt >> 16);
            saltBytes[2] = (byte) (salt >> 8);
            saltBytes[3] = (byte) (salt);

            byte[] passwordBytes = UTF8Encoding.UTF8.GetBytes(password);

            Byte[] preHashed = new Byte[saltBytes.Length + passwordBytes.Length];
            System.Buffer.BlockCopy(passwordBytes, 0, preHashed, 0, passwordBytes.Length);
            System.Buffer.BlockCopy(saltBytes, 0, preHashed, passwordBytes.Length, saltBytes.Length);

            SHA1 sha1 = SHA1.Create();
            return sha1.ComputeHash(preHashed);
        }

XML文件的生成方式:

 private void btnSave_Click(object sender, System.EventArgs e)
        {
            int salt = GenerateSaltForPassword();

            string fileName = System.IO.Path.Combine(Application.StartupPath, "alphaService.xml");
            XDocument doc = new XDocument();
            XElement xml = new XElement("Info",
                new XElement("DatabaseServerName", txtServerName.Text),
                new XElement("DatabaseUserName", txtDatabaseUserName.Text),
                new XElement("DatabasePassword", ComputePasswordHash(txtDatabasePassword.Text, salt)),
                new XElement("ServiceAccount", txtAccount.Text),
                new XElement("ServicePassword", ComputePasswordHash(txtServicePassword.Text, salt)));

            doc.Add(xml);
            doc.Save(fileName);
        }

【问题讨论】:

  • 如果我理解你的要求,你不能。散列是一种单向过程,这意味着您不能(“以编程方式”)恢复(或解密)原始值。这就是为什么它被用于存储密码。
  • 我不明白。如果它用于存储密码,则必须有一种方法可以使用该密码。我应该怎么做?无论如何,我怎样才能从 XML 中提取该值?
  • 读起来很简单,但最终的结果是没用的。您最终会得到一个您将无法用于连接的实际密码的哈希值。要阅读它,请执行以下操作:XDocument doc = XDocument.Load(pathToXml"); string password = doc.Descendants("DatabasePassword").FirstOrDefault().Value;.
  • 感谢 XML 代码。

标签: c# xml encryption hash


【解决方案1】:

正如 Andrei 正确指出的那样,散列密码的全部意义在于无法检索密码。这是一种非常标准的技术,可以帮助保护密码文件被盗(被黑客)。使用此文件的方式是当用户尝试进行身份验证时,从 DB(或在您的情况下为 XML)读取盐,添加到输入密码的方式与设置密码时相同(在您的代码中,它附加到密码字节),然后将生成的哈希与存储的哈希进行比较。如果相同,则用户输入的密码正确,否则密码错误。所以可以进行密码验证,但密码本身无法恢复。

现在,如果不使用盐或弱盐,则可以使用 rainbow tables 反向哈希,但这更像是一种黑客技术,不适合您的目的。

如此之短,您无法从哈希中恢复密码,因为这就是它首先被哈希的原因。

【讨论】:

  • 谢谢。这是设置/配置实用程序的一部分。那么如何实现不将密码明文存储在 XML 文件中,然后使用它在已安装的 Windows 服务中设置连接字符串的目标呢?
  • 跳出框框:您是否考虑过使用受信任的连接(如果是 SQLServer)进行身份验证?如果信任不是一个选项,那么您需要研究加密而不是散列,并在存储中加密您的密码。请小心,因为您需要将密钥存储在某处进行解密,如果您在代码中执行此操作,则可以使用 RedGate 的 .NET Reflector 或 JetBrains 的 dotPeak 等实用程序轻松检索它。 This article 可能会有所帮助。
  • 我正在尝试研究加密stackoverflow.com/questions/21912438/…>
  • 你浏览过我在评论中发布的链接中的文章吗?
  • 是的,请在此处查看我的评论。我无法将其存储为配置文件。有两个可执行文件,一个是存储密码的配置实用程序,另一个是必须读取密码的已安装 Windows 服务。这就是我想到使用 XML 文件的原因。
猜你喜欢
  • 2015-02-17
  • 2015-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-02
  • 2011-10-29
  • 2012-03-24
相关资源
最近更新 更多