【问题标题】:Password hashing in a C# Windows app, absent ASP.NET's FormsAuthentication?C# Windows 应用程序中的密码散列,缺少 ASP.NET 的 FormsAuthentication?
【发布时间】:2010-09-17 18:51:39
【问题描述】:

我的 Win 表单应用程序似乎不喜欢 FormsAuthentication,我对哈希完全陌生,因此非常欢迎任何帮助转换它。谢谢。

//Write hash
protected TextBox tbPassword;
protected Literal liHashedPassword;

{
  string strHashedPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(tbPassword.Text, "sha1");
  liHashedPassword.Text = "Hashed Password is: " + strHashedPassword;    
}

//read hash
string strUserInputtedHashedPassword = FormsAuthentication.HashPasswordForStoringInConfigFile( tbPassword.Text, "sha1");
if(strUserInputtedHashedPassword == GetUsersHashedPasswordUsingUserName(tbUserName.Text))
{
  // sign-in successful
}
else
{
  // sign-in failed
}

【问题讨论】:

  • 目标是拥有一个允许用户指定与登录用户不同的凭据的应用程序吗?获取用于访问其他服务的凭据?我不确定您要做什么。

标签: c# .net hash passwords


【解决方案1】:
using System.Security.Cryptography;

public static string EncodePasswordToBase64(string password)
{  byte[] bytes   = Encoding.Unicode.GetBytes(password);
   byte[] inArray = HashAlgorithm.Create("SHA1").ComputeHash(bytes);
   return Convert.ToBase64String(inArray);
}  

【讨论】:

  • 非常干净——我测试了我们的两个实现,你的更快一点。100,000 次迭代快了 50 毫秒,所以我赞成 :)
  • 请记住,SHA1(显然)更快,但不如 SHA256 安全。请参阅en.wikipedia.org/wiki/SHA256 了解更多信息
  • @JarrodDixon:恰恰相反。对于密码,你需要一个 slower 散列。
【解决方案2】:

FormsAuthentication 是在 System.Web.dll 程序集中的 System.Web.Security 命名空间中定义的。

仅仅因为您正在编写一个 WinForm 应用程序并不会阻止您使用该命名空间或引用该程序集;它们只是默认情况下不会像 WebForms 应用程序那样完成。

【讨论】:

    【解决方案3】:

    如果您将哈希用于用户凭据,我建议您做的不仅仅是哈希,理想情况下您还需要密钥拉伸。

    这里有一个 API 可以安全地做你想做的事:

    https://sourceforge.net/projects/pwdtknet/

    【讨论】:

    • 我在那里看不到任何源代码。不确定是否有人会将他们的密码信任给他们一无所知的 .DLL。
    • Source 位于名为“source”的文件夹的文件区域中。提供的来源正是您描述的原因。这是源文件夹的链接sourceforge.net/projects/pwdtknet/files/Source
    【解决方案4】:

    我认为它应该有效。您需要做的就是在您的代码中引用 System.Web.Security(并将其作为引用添加到您的 Visual Studio 项目中)。

    【讨论】:

      【解决方案5】:

      如果您确实必须“发布”此表单应用程序,那么添加 System.Web.Security 可能不是一个好主意...

      如果您需要 SHA1 哈希,msdn 上有一个非常易于使用的 .net 密码库和示例。关键是

      1. 获取您想要加密的内容
      2. 将其转换为您使用的任何编码(ascii、utf*)的字节
      3. 使用 .Net 内置的众多散列方案之一来获取散列字节
      4. 将这些字节转换回与步骤 2 中编码相同的字符串
      5. 将生成的哈希字符串保存在某处以供以后比较

      //step 1 and 2
      byte[] data = System.Text.Encoding.Unicode.GetBytes(tbPassword.Text,);
      byte[] result; 
      
      //step 3
      SHA1 sha = new SHA1CryptoServiceProvider(); 
      result = sha.ComputeHash(data);
      
      //step 4
      string storableHashResult = System.Text.Encoding.Unicode.ToString(result);
      
      //step 5
          // add your code here
      

      【讨论】:

      • 除了明显的“它不适用于 WinForms 应用程序”之外,是否有理由说明包含 System.Web.* 不是一个好主意?
      • 让我想起了 Rick Strahl 在west-wind.com/Weblog/posts/617930.aspx 1 的帖子。它“感觉”不太对。 2. 它强制 System.Web 进入任何使用该库的应用程序的已加载组件列表。 3. 它增加了 2.5 兆的内存占用,只是为了加载它。 4. 等(房间外)
      【解决方案6】:

      你能不使用 BitConverter 函数代替“x2”循环吗?

      例如

      return BitConverter.ToString(hash).Replace("-", "");

      【讨论】:

        猜你喜欢
        • 2014-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多