mirror of
https://github.com/ACEmulator/ACE
synced 2026-08-17 12:26:06 -04:00
* Change WorkFactor to 8 * Add configuration option for password workfactor, and migration option to support [up/down]grade at runtime * Fix a default * Do not pass in values less 4 and greater than 31 to prevent server crash * Update defaults
105 lines
3.8 KiB
C#
105 lines
3.8 KiB
C#
using ACE.Common.Cryptography;
|
|
|
|
using log4net;
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace ACE.Database.Models.Auth
|
|
{
|
|
public static class AccountExtensions
|
|
{
|
|
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
public static bool PasswordMatches(this Account account, string password)
|
|
{
|
|
if (account.PasswordSalt == "use bcrypt") // Account password is using bcrypt
|
|
{
|
|
if (Common.ConfigManager.Config.Server.Accounts.ForceWorkFactorMigration &&
|
|
(BCryptProvider.GetPasswordWorkFactor(account.PasswordHash) != Common.ConfigManager.Config.Server.Accounts.PasswordHashWorkFactor))
|
|
// Upgrade (or downgrade) Password workfactor if not the same as config specifies, ForceWorkFactorMigration is TRUE and Password Matches
|
|
{
|
|
if (BCryptProvider.Verify(password, account.PasswordHash))
|
|
{
|
|
account.SetPassword(password);
|
|
account.SetSaltForBCrypt();
|
|
|
|
DatabaseManager.Authentication.UpdateAccount(account);
|
|
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
else
|
|
return BCryptProvider.Verify(password, account.PasswordHash);
|
|
}
|
|
else // Account password is using SHA512 salt
|
|
{
|
|
log.Debug($"{account.AccountName} password verified using SHA512 hash/salt, migrating to bcrypt.");
|
|
|
|
var input = GetPasswordHash(account, password);
|
|
|
|
if (input == account.PasswordHash) // If password matches, migrate to bcrypt
|
|
{
|
|
account.SetPassword(password);
|
|
account.SetSaltForBCrypt();
|
|
|
|
DatabaseManager.Authentication.UpdateAccount(account);
|
|
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static void SetPassword(this Account account, string value)
|
|
{
|
|
account.PasswordHash = GetPasswordHash(value);
|
|
}
|
|
|
|
public static void SetSalt(this Account account, string value)
|
|
{
|
|
account.PasswordSalt = value;
|
|
}
|
|
|
|
public static void SetSaltForBCrypt(this Account account)
|
|
{
|
|
SetSalt(account, "use bcrypt"); // this is used just to indicate that the password is using bcrypt. For migration purposes only.
|
|
}
|
|
|
|
private static string GetPasswordHash(string password)
|
|
{
|
|
var workFactor = Common.ConfigManager.Config.Server.Accounts.PasswordHashWorkFactor;
|
|
|
|
if (workFactor < 4)
|
|
{
|
|
log.Warn("PasswordHashWorkFactor in config less than minimum value of 4, using 4 and continuing.");
|
|
workFactor = 4;
|
|
}
|
|
else if (workFactor > 31)
|
|
{
|
|
log.Warn("PasswordHashWorkFactor in config greater than minimum value of 31, using 31 and continuing.");
|
|
workFactor = 31;
|
|
}
|
|
|
|
return BCryptProvider.HashPassword(password, workFactor);
|
|
}
|
|
|
|
private static string GetPasswordHash(Account account, string password)
|
|
{
|
|
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
|
|
byte[] saltBytes = Convert.FromBase64String(account.PasswordSalt);
|
|
byte[] buffer = passwordBytes.Concat(saltBytes).ToArray();
|
|
byte[] hash;
|
|
|
|
using (SHA512Managed hasher = new SHA512Managed())
|
|
hash = hasher.ComputeHash(buffer);
|
|
|
|
return Convert.ToBase64String(hash);
|
|
}
|
|
}
|
|
}
|