Merge pull request #2504 from Pryaxis/h/hashing
Remove DIY password hashing crypto
This commit is contained in:
commit
6cd69324c7
3 changed files with 3 additions and 75 deletions
|
|
@ -14,6 +14,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
|
|||
|
||||
## Upcoming changes
|
||||
* Fixed the `/respawn` command to permit respawning players from the console. (@hakusaro, @Kojirremer)
|
||||
* Removed the old password hashing system, which predated `bcrypt` hashes and allowed specifying the hash algorithm in the config file. This also removes the config option for setting the hash algorithm (`HashAlgorithm`). This is because it helps clear the way for .NET5/6 and OTAPI 3, and because `bcrypt` has been the default since TShock 4.3 in 2015. (@hakusaro)
|
||||
|
||||
## TShock 4.5.6
|
||||
* Updated Linux guide. (@NezbednikSK)
|
||||
|
|
|
|||
|
|
@ -368,11 +368,6 @@ namespace TShockAPI.Configuration
|
|||
[Description("The minimum password length for new user accounts. Can never be lower than 4.")]
|
||||
public int MinimumPasswordLength = 4;
|
||||
|
||||
/// <summary>The hash algorithm used to encrypt user passwords.
|
||||
/// Valid types: "sha512", "sha256" and "md5". Append with "-xp" for the xp supported algorithms.</summary>
|
||||
[Description("The hash algorithm used to encrypt user passwords. Valid types: \"sha512\", \"sha256\" and \"md5\". Append with \"-xp\" for the xp supported algorithms.")]
|
||||
public string HashAlgorithm = "sha512";
|
||||
|
||||
/// <summary>Determines the BCrypt work factor to use. If increased, all passwords will be upgraded to new work-factor on verify.
|
||||
/// The number of computational rounds is 2^n. Increase with caution. Range: 5-31.</summary>
|
||||
[Description("Determines the BCrypt work factor to use. If increased, all passwords will be upgraded to new work-factor on verify. The number of computational rounds is 2^n. Increase with caution. Range: 5-31.")]
|
||||
|
|
|
|||
|
|
@ -438,7 +438,7 @@ namespace TShockAPI.DB
|
|||
{
|
||||
try
|
||||
{
|
||||
if (BCrypt.Net.BCrypt.Verify(password, Password))
|
||||
if (BCrypt.Net.BCrypt.Verify(password, Password))
|
||||
{
|
||||
// If necessary, perform an upgrade to the highest work factor.
|
||||
UpgradePasswordWorkFactor(password);
|
||||
|
|
@ -447,35 +447,12 @@ namespace TShockAPI.DB
|
|||
}
|
||||
catch (SaltParseException)
|
||||
{
|
||||
if (String.Equals(HashPassword(password), Password, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
// The password is not stored using BCrypt; upgrade it to BCrypt immediately
|
||||
UpgradePasswordToBCrypt(password);
|
||||
return true;
|
||||
}
|
||||
TShock.Log.ConsoleError("Error: Unable to verify the password hash for user {0} ({1})", Name, ID);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>Upgrades a password to BCrypt, from an insecure hashing algorithm.</summary>
|
||||
/// <param name="password">The raw user account password (unhashed) to upgrade</param>
|
||||
protected void UpgradePasswordToBCrypt(string password)
|
||||
{
|
||||
// Save the old password, in the event that we have to revert changes.
|
||||
string oldpassword = Password;
|
||||
|
||||
try
|
||||
{
|
||||
TShock.UserAccounts.SetUserAccountPassword(this, password);
|
||||
}
|
||||
catch (UserAccountManagerException e)
|
||||
{
|
||||
TShock.Log.ConsoleError(e.ToString());
|
||||
Password = oldpassword; // Revert changes
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Upgrades a password to the highest work factor available in the config.</summary>
|
||||
/// <param name="password">The raw user account password (unhashed) to upgrade</param>
|
||||
protected void UpgradePasswordWorkFactor(string password)
|
||||
|
|
@ -536,51 +513,6 @@ namespace TShockAPI.DB
|
|||
Password = BCrypt.Net.BCrypt.HashPassword(password.Trim(), workFactor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary of hashing algorithms and an implementation object.
|
||||
/// </summary>
|
||||
protected readonly Dictionary<string, Func<HashAlgorithm>> HashTypes = new Dictionary<string, Func<HashAlgorithm>>
|
||||
{
|
||||
{"sha512", () => new SHA512Managed()},
|
||||
{"sha256", () => new SHA256Managed()},
|
||||
{"md5", () => new MD5Cng()},
|
||||
{"sha512-xp", () => SHA512.Create()},
|
||||
{"sha256-xp", () => SHA256.Create()},
|
||||
{"md5-xp", () => MD5.Create()},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hashed string for a given string based on the config file's hash algo
|
||||
/// </summary>
|
||||
/// <param name="bytes">bytes to hash</param>
|
||||
/// <returns>string hash</returns>
|
||||
protected string HashPassword(byte[] bytes)
|
||||
{
|
||||
if (bytes == null)
|
||||
throw new NullReferenceException("bytes");
|
||||
Func<HashAlgorithm> func;
|
||||
if (!HashTypes.TryGetValue(TShock.Config.Settings.HashAlgorithm.ToLower(), out func))
|
||||
throw new NotSupportedException("Hashing algorithm {0} is not supported".SFormat(TShock.Config.Settings.HashAlgorithm.ToLower()));
|
||||
|
||||
using (var hash = func())
|
||||
{
|
||||
var ret = hash.ComputeHash(bytes);
|
||||
return ret.Aggregate("", (s, b) => s + b.ToString("X2"));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hashed string for a given string based on the config file's hash algo
|
||||
/// </summary>
|
||||
/// <param name="password">string to hash</param>
|
||||
/// <returns>string hash</returns>
|
||||
protected string HashPassword(string password)
|
||||
{
|
||||
if (string.IsNullOrEmpty(password) && Password == "non-existant password")
|
||||
return "non-existant password";
|
||||
return HashPassword(Encoding.UTF8.GetBytes(password));
|
||||
}
|
||||
|
||||
#region IEquatable
|
||||
|
||||
/// <summary>Indicates whether the current <see cref="UserAccount"/> is equal to another <see cref="UserAccount"/>.</summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue