A. Gladkiy
A. Gladkiy

Reputation: 3450

Temporary save password in db ASP.NET Core

I'm developing .NET Core app + Identity. I want to implement user signing up. User enter your data login/password etc. And the next step I need to confirm email and I don't want to create user in db before he confirm email, because I need to create new db for him. I want to save data to temp table in db. And after confirmation I will take data from there and continue with registration and after that remove record from temp table.

But as I see Identity has method userManager.Create(user, password) with password in clear text.

Do I need hash/dehash password algorithm? If yes, then what is it? What is the best approach to store secure password in temp table?

Upvotes: 4

Views: 1069

Answers (4)

A. Gladkiy
A. Gladkiy

Reputation: 3450

So, I did the following:

1) Generate password for user = null (first parameter):

var hashPassword = _passwordHasher.HashPassword(null, command.Password);

2) When user confirm email, I create him with default password that go through password validation settings in Startup.cs class:

_userManager.CreateAsync(user, "123456");

3) Update PasswordHash column and user with value from step 1:

user.PasswordHash = command.PasswordHash;
_userManager.UpdateAsync(user);

Upvotes: 0

user7270881
user7270881

Reputation: 19

The best I think is SHA1 hash algorithm, it is 128 bit by standard. I remember when I did my PHP thesis using it :). It is the most secure of all.

Use Forms Authentication ( https://msdn.microsoft.com/en-us/library/t8yy6w3h.aspx ):

<configuration>
<connectionStrings>
     <add name="SqlServices" connectionString="Data Source=MySqlServer;Integrated Security=SSPI;Initial Catalog=aspnetdb;" />
</connectionStrings>
<system.web>
  <authentication mode="Forms">
    <forms loginUrl="login.aspx" />
  </authentication>
  <authorization>
    <deny users="?" />
  </authorization>
  <membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="20">
  <providers>        
    <add name="SqlProvider"
      type="System.Web.Security.SqlMembershipProvider"
      connectionStringName="SqlServices"
      enablePasswordRetrieval="false"
      enablePasswordReset="true"
      requiresQuestionAndAnswer="false"
      passwordFormat="Hashed"
      applicationName="/" />
  </providers>
</membership>
</configuration>
</system.web>

U just change the instance name and the login page. The default hash alg. is SHA1 and it changes to HMACSHA256 or SHA256 in the .NET 4.0 Framework. U can override it:

<membership
    defaultProvider="provider name"
    userIsOnlineTimeWindow="number of minutes"
    hashAlgorithmType="SHA1">
    <providers>...</providers>
</membership>

You can specify the greatest SHA your .NET version supports, for .NET 4 and latest is SHA512, but the default value must be ok.

To add yours you can read here (it is just a .dll to be configured in machine.config or possibly also in web.config, if u don't want to use it globally):

https://msdn.microsoft.com/en-us/library/693aff9y.aspx

Use Membership.Validate to validate the user at log-on.

If you use the new MVC thing that came 2013 there is UserManager u simply implement your User that holds the email, that's all, it must be IUser. There is a method UserManager.CreateUser(TUser user, string password)

Upvotes: -1

M. Wiśnicki
M. Wiśnicki

Reputation: 6203

Necessarily you have to use some hash algorithm. Identity uses Password-Based Key Derivation Function 2 (PBKDF2) - wiki. Here is sample hash password method.

public static string HashPass(string pwd)
{
    byte[] salt;
    byte[] bytes;

    using (Rfc2898DeriveBytes rfc2898DeriveByte = new Rfc2898DeriveBytes(pwd, 16, 1000))
    {
        salt = rfc2898DeriveByte.Salt;
        bytes = rfc2898DeriveByte.GetBytes(32);
    }
    byte[] num = new byte[49];
    Buffer.BlockCopy(salt, 0, num, 1, 16);
    Buffer.BlockCopy(bytes, 0, num, 17, 32);
    return Convert.ToBase64String(num);
}

Better idea will be used UserAccount table with some status where you can store status about user account:

public class UserAccount
{
   public int AccountId {  get; set;}

   public UserAccountStatus AccountStatus { get; set; }

}

public enum UserAccountStatus 
{
   Pending = 0,
   UsingTempPassword = 1
   Active = 2
}

Upvotes: 0

Dawid Rutkowski
Dawid Rutkowski

Reputation: 2756

No you don't need - I will be automatically hashed in the database by UserManager.

In my opinion it's not good idea to create temporary record. Simply create user, mark it as inactive until he will confirm his email. That's the right approach.

Upvotes: 2

Related Questions