手动散列密码与ASP.NET Identity v2.2.1相同

时间:2016-09-07 15:45:42

标签: asp.net-identity-2 password-hash

我有一个ASP.NET Web Api,它使用ASP.NET Identity v2.2.1来管理用户。我可以毫无问题地添加/编辑用户。但是,我有第二个项目无法使用API​​,但需要能够直接通过数据库更改Users密码。

我试图找出如何散列用户输入的密码而不通过API。我需要确保我使用的是ASP.NET身份使用的相同哈希算法。我在this SO article中遇到了一些代码,但我不确定它是否与v2.2.1使用的哈希算法相同。

using using System.Security.Cryptography;

public static string HashPassword(string password)
{
    private const int PBKDF2IterCount = 1000; // default for Rfc2898DeriveBytes
    private const int PBKDF2SubkeyLength = 256 / 8; // 256 bits
    private const int SaltSize = 128 / 8; // 128 bits

    if (password == null)
    {
        throw new ArgumentNullException("password");
    }

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

    var 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);
}

我想避免将ASP.NET Identity添加为此项目的依赖项,因此我希望手动hash密码。

1 个答案:

答案 0 :(得分:0)

我建议你使用SimpleCrypto

这就是我在项目中使用它的方式,我相信这会对你有所帮助。可以从DLL

添加此nuget
         [HttpPost]
     public ActionResult Register(RegisterViewModel model)
     {
         try
         {
             if (ModelState.IsValid)
             {
                 {
                     var crypto = new SimpleCrypto.PBKDF2();
                     var encrypPass = crypto.Compute(model.Password);
                     var newUser = db.Users.Create();
                     newUser.Email = model.Email;
                     newUser.Password = encrypPass;
                     newUser.PasswordSalt = crypto.Salt;
                    // newUser.Name = model.UserName;
                     newUser.Username = model.UserName;
                     //newUser.AddedBy = model.;
                     db.Users.Add(newUser);
                     db.SaveChanges();
                     return RedirectToAction("Index", "Home");
                 }
             }
             else
             {
                 ModelState.AddModelError("", "");
             }
         }
         catch (DbEntityValidationException e)
         {
             foreach (var eve in e.EntityValidationErrors)
             {
                 Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                     eve.Entry.Entity.GetType().Name, eve.Entry.State);
                 foreach (var ve in eve.ValidationErrors)
                 {
                     Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                         ve.PropertyName, ve.ErrorMessage);
                 }
             }
             throw;
         }

         return View();
     }

登录时的有效检查将是这样的

        private bool IsValid(string email, string password)
    {
        var crypto = new SimpleCrypto.PBKDF2();
        bool isValid = false;

        {
            var user = db.Users.FirstOrDefault(u => u.Email == email);
            if (user != null)
            {
               if (user.Password == crypto.Compute(password, user.PasswordSalt))
                {
                    isValid = true;
                }
            }
        }
        return isValid;
    }