2014-02-20 79 views
0

大部分我已经在这个节目密码散列/盐渍密码比较感兴趣的课题。这不是我的用例。我需要从xml文件中读取散列/盐渍密码,然后使用它登录到Sql数据库。我需要从Windows服务中执行此操作。我首先不确定如何阅读XML文件中的条目,然后如何“解密”它?提取/解密散列/盐渍密码了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); 
     } 
+2

如果我理解正确,您的要求,你不能。哈希是一种单向过程,意味着您不能(以编程方式)恢复(或解密)原始值。这就是它用于存储密码的原因。 –

+0

我不明白。如果它用于存储密码,则必须有一种方法来使用该密码。我应该做什么?无论如何,我怎样才能从XML中提取这个值呢? – user2471435

+0

读它很简单,但最终的结果是没用的。你最终会得到一个你不能用来连接的密码。读它,这样做:'的XDocument DOC = XDocument.Load(pathToXml “);字符串密码= doc.Descendants(” DatabasePassword“)FirstOrDefault()值;' –

回答

3

正如安德烈正确地指出,散列密码的全部意义在于使密码不能被检索。这是一个非常标准的技术,可以帮助保护万一密码文件被黑客窃取。使用此文件的方式是当用户尝试进行身份验证时,从DB读取salt(或者在您的情况下使用XML),将其添加到输入的密码中,方法与设置密码的方式相同(在您的代码中,它被附加到密码字节),然后将结果散列与存储的散列进行比较。如果相同,用户输入正确的密码,否则密码不正确。因此可以完成密码验证,但密码本身无法恢复。

现在,如果不使用盐或弱盐,可能会使用rainbow tables反向散列回来,但这更多是一种黑客技术,不适合您的目的。

所以它的短,你不能从哈希值作为这就是为什么它首先被散列的原因恢复密码。

+0

谢谢。。你这是一个设置/配置实用程序的一部分。那么,如何做到不存储在XML文件中明确测试的密码,然后用它来建立在已安装的Windows服务的连接字符串的目标是什么? – user2471435

+0

去一你是否考虑过使用可信连接(如果它是SQLServer)来进行身份验证?如果受信任不是一个选项,那么你需要考虑加密而不是散列,并且在存储中加密你的密码。需要存储的关键地方来解密,如果你在代码中做到这一点,它可以很容易地与像展鹏的.net反射或JetBrains公司dotPeak公用事业检索。[本文](http://msdn.microsoft.com/ EN-US /李brary/zhhddkxy(v = vs.100).aspx)可能会有所帮助。 – LB2

+0

我试图寻找到加密这里>/a> – user2471435