首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >System.Web.Helpers.Crypto -盐在哪里?

System.Web.Helpers.Crypto -盐在哪里?
EN

Stack Overflow用户
提问于 2013-07-17 15:38:12
回答 2查看 9.9K关注 0票数 32

在过去,当处理密码时,我总是在我的数据存储中分别存储一个盐密码和一个散列密码。今天,我希望更新一些遗留代码,以使用RFC2898散列值。我偶然发现了来自System.Web.HelpersCrypto.Hash方法。看起来这些将为我做大部分繁重的工作。有GenerateSalt()HashPassword()VerifyHashedPassword()方法。HashPassword()VerifyHashedPassword()方法不接受Salt值。HashPassword()方法的MSDN文档中写道:

“生成的哈希字节流的格式为{0x00,salt,subkey},它在返回之前采用base-64编码。”

我需要担心盐吗?文档似乎说盐将自动生成并存储在base-64编码值中?这是正确的吗?我只需要存储从HashPassword()返回的字符串

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-20 11:01:21

回答

所有密码都需要加盐,以便安全地散列它们。然而,在这种情况下,您是正确的。System.Web.Helpers.Crypto会为你创建一个salt。您不需要创建一个。它存储在由Crypto.HashPassword()返回的字符串中。

示例

你所需要做的就是这样。

代码语言:javascript
复制
using System.Web.Helpers;

public void SavePassword(string unhashedPassword)
{
    string hashedPassword = Crypto.HashPassword(unhashedPassword);
    //Save hashedPassword somewhere that you can retrieve it again.
    //Don't save unhashedPassword! Just let it go.
}

public bool CheckPassword(string unhashedPassword)
{
    string savedHashedPassword = //get hashedPassword from where you saved it

    return Crypto.VerifyHashedPassword(savedHashedPassword, unhashedPassword)
}

更多信息

如果你想看Crypto类的源代码,可以查看here.

  • And

  • 是关于这个类及其背后的一些想法的一个很好的博客。
票数 55
EN

Stack Overflow用户

发布于 2014-07-01 15:14:58

我只想分享这篇文章:

http://forums.asp.net/t/1842429.aspx?System+Web+Helpers+Crypto+HashPassword

你好,

我一直在研究System.Web.Helpers中新的Crypto HashPassword和VerifyMethod方法。

这两种方法都使用了Salt,但它们都不返回Salt,只返回Hash。

我不需要Salt把它存储在数据库里吗?我是不是遗漏了什么?

谢谢,

米格尔

。。

您将在用户创建帐户时生成salt,然后在调用HashPassword之前将其附加到

。然后将该盐和散列密码存储在数据库中。在验证凭据时,只需在调用VerifyHashedPassword之前从数据库中读取salt并将其附加到登录的密码之后。BrockAllen

。。

不确定我是否理解它...因为在HashPassword中,Salt是在方法内部生成的:

米格尔

代码语言:javascript
复制
// Method in Crypto class
public static string HashPassword(string password)
{
    if (password == null)
    {
        throw new ArgumentNullException("password");
    }

    // Produce a version 0 (see comment above) password hash.
    byte[] salt;
    byte[] subkey;
    using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount))
    {
        salt = deriveBytes.Salt;
        subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
    }

    byte[] outputBytes = new byte[1 + SaltSize + PBKDF2SubkeyLength];
    Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
    Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, PBKDF2SubkeyLength);
    return Convert.ToBase64String(outputBytes);
}

。。

BrockAllen 2012年9月11日下午07:50

是的,忽略这一点--它是Rfc2898DeriveBytes的内部盐,它派生自密码,所以在存储密码的上下文中,它不是真正的盐,因为它总是为相同的密码重新创建。您将仍然希望在密码字符串级执行您自己的salt。所以就像这样:

代码语言:javascript
复制
public void CreateAccount(string username, string password)
{
    var salt = Crypto.GenerateSalt();
    var saltedPassword = password + salt;
    var hashedPassword = Crypto.HashPassword(saltedPassword);
    CreateAccount(username, salt, hashedPassword);
}

public void Verify(string username, string password)
{
    var salt = GetSaltForUserFromDatabase(username);
    var hashedPassword = GetHashedPasswordForUserFromDatabase(username);
    var saltedPassword = password + salt;
    if (Crypto.VerifyHashedPassword(hashedPassword, saltedPassword))
    {
        // valid password for this username
    }
}

这将允许您在数据库中存储您的盐以及散列的加盐密码。

有关使用salt进行密码散列的其他信息,请参阅本文:https://crackstation.net/hashing-security.htm

存储密码的步骤

  1. 使用CSPRNG生成一个长的随机盐。
  2. 将盐预先添加到密码中,并使用标准加密散列函数(如SHA256 )对其进行散列。
  3. 将盐和散列都保存在用户的数据库记录中。

验证密码的步骤

  1. 从database.
  2. Prepend检索用户的盐和散列,并使用与给定密码的散列相同的散列对其进行散列。如果它们匹配,则密码正确。否则,密码不正确。

Crypto类的源代码:

http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Helpers/Crypto.cs

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17693918

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档