密码加密

3

我正在使用C#为一个应用程序创建登录界面。在我的登录界面中,我正在从数据库中读取用户名和密码,并检查输入的用户名和密码是否正确。我需要在读取数据库中的密码时将其加密。有人能解释一下加密和解密的工作原理吗。

  1. Whether I have to store the encrypted value in the database for reading.
  2. Right now I have two fields

    column names: username         password 
    
    values:        admin            password
    
  3. Should I store the encrypted value of the password in another field in the login table?


7
密码应该是经过加盐哈希处理的,而不是被加密的。 - Mitch Wheat
2
可能是重复的内容,与密码加密相似。 - Alastair Pitts
5个回答

14

首先:现在通常的方法是将密码的盐值哈希存储,而不是明文密码本身(建议使用SHA-1等更好的哈希算法,避免使用MD5因为它已经不安全了)。当用户登录时,重新计算输入字符串的哈希值,然后将其与数据库中存储的字符串进行比较。

编辑:为什么不应该使用加密来保护密码?因为当攻击者知道加密的密钥时,所有密码都会被暴露(这很糟糕)。如果你使用哈希,他只能逐个猜测(这并不容易)。此外,哈希算法通常比加密更快,你可以获得性能优势。

编辑:为什么应该存储盐值哈希,而不是哈希值?因为哈希算法保证如果你哈希相同的字符串,结果是相同的。这可能会导致一个问题,即当攻击者看到相同的哈希值时,他可以“猜测”文本是相同的,这给了他获取原始密码的机会。

盐值是指除原始文本外,还要加入一些随机文本,因此,两个相同的字符串将生成不同的哈希值

请看这个:http://www.obviex.com/samples/hash.aspx

如果用户忘记了密码,你可以使用重置密码功能,许多网站都在使用:

  1. 用户请求重置密码
  2. 一个电子邮件包含一个特殊的链接(包括一个秘密令牌/PIN)将被发送到注册的电子邮件地址,允许用户重置他的密码。
  3. 一个随机创建的密码将再次发送给用户,然后他可以登录并更改他的密码。

更新于2012年5月14日:答案似乎已经过时,并且不完全正确。人们正在转向更安全的哈希-加密算法来存储密码。其中一个值得注意的解决方案是bcrypt,另一个(新的有前途的)是scrypt。

这些加密方式的好处?它们很慢!比哈希算法慢得多。借助 GPU(例如,nVidia 的 CUDA),破解哈希值现在不是不可能了,而这种慢速性质可以让破解这些加密变得更加困难。
您可以在以下网址找到有关 bcrypt 的更多信息:http://codahale.com/how-to-safely-store-a-password/ 其次,您应该将用户表(包含用户配置文件,例如全名、出生日期、地址等)和登录表(包含用户名和密码以及一些特殊属性)分开。这将导致更好的管理,并减少暴露敏感信息的风险。

为什么会得到-1分?盐哈希比加密/解密更安全无限。 - Alastair Pitts
不知道,但SHA-1不安全,使用PKDBF2或bcrypt,这两个算法都内置了盐。 - Richard Gadsden

1

除了给出的建议外,还有其他方法来保护密码:

  1. 一次性密码:尽管实现了盐哈希,密码仍然存储在硬盘上,容易被破解。因此,在这里需要采用更好的方法。与静态密码相比,一次性密码每次用户登录系统时都会更改,并且通常用户应携带用于与服务器同步的小型硬件。主要有两种OTP类型:(访问使用一次性密码进行更安全的身份验证

    • 时间同步
    • 计数器同步
  2. 使用BCrypt,它使用Blowfish加密算法的变体键调度,并包含一个工作因素,让您确定哈希函数的成本。为了熟悉bCrypt,请访问:http://codahale.com/how-to-safely-store-a-password/

在C#中,您可以使用BCrypt.Net库,它是iBCrypt库的一个移植版本:阅读以下文章以了解如何在Visual Studio.Net中启动和运行此库: 在.NET应用程序中使用BCrypt-为什么它比SHA或MD5更好。 当然,在SO中有很多关于这个算法的讨论,搜索并深入研究更多相关内容。

0

您是否正在实现自己的身份验证机制?您可以使用已经存在的System.Web.Security Microsoft身份验证。通过使用Membership类,您可以在不从数据库检索密码的情况下验证用户密码。这样,您就可以将加盐(加密)密码存储在数据库中。只需使用Membership.CreateUser和Membership.ValidateUser即可。 如果您不需要(从性能或专有实现方面考虑),请使用现有的实现并节省时间。


-1

密码应该以加密的方式存储在数据库中。当用户尝试登录时,使用相同的算法对密码进行加密,然后将其与数据库中的值进行比较。

通常使用MD5进行密码加密,因为它无法被解密。如果用户忘记了密码,则无法检索密码,但只能重置密码。

希望这可以帮助您!


加密和哈希是使用不同算法的两个不同的概念,请勿混淆。 - V4Vendetta

-3

你可以用多种方式加密密码。

其中一种方式是使用 MD5 加密。让我向你展示我正在使用的加密方法之一。

#region Encrypt
public string Encrypt(string simpletext, string keys)
{
    try
    {
        XCryptEngine xe = new XCryptEngine();

        xe.Algorithm = XCrypt.XCryptEngine.AlgorithmType.DES; //DES = Data Encryption Standard

        string cipher = xe.Encrypt(simpletext, keys);
        if (cipher != null)
            return (cipher);
        else
            return null;
    }

    catch (Exception ex)
    {
        throw ex;
    }
}
#endregion

#region Decrypt
public string Decrypt(string simpletext, string keys)
{
    try
    {
        XCryptEngine xe = new XCryptEngine();

        xe.Algorithm = XCrypt.XCryptEngine.AlgorithmType.DES;

        //Console.WriteLine(xe.Decrypt(simpletext, keys));
        simpletext = simpletext.Replace(" ", "+");
        string cipertext = xe.Decrypt(simpletext, keys);
        if (cipertext != null)
            return (cipertext);
        else
            return null;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}
#endregion

你需要使用引用来使用XCrypt。

using XCrypt;

你提到了MD5哈希,但是你的方法执行DES加密。哈希对于密码来说更好,因为它不能被反转。还要注意XCrypt不是.NET BCL的一部分,需要单独下载。 - Xavier Poinas
我一直以为MD5哈希!(请重新措辞,你的回答有误导性) - V4Vendetta
我提到了MD5,因为它被广泛使用。虽然我已经描述了我正在使用的方法,但MD5是常用的。 - Bhavik Goyal
MD5不是加密,而是具有密码学安全性的哈希函数。而且你的示例并没有使用MD5,而是使用了DES。 - Richard Gadsden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接