Chad
03/28/2024, 1:00 AMD_Inventor
03/28/2024, 5:56 AMChad
03/28/2024, 5:57 AMChad
03/28/2024, 5:57 AMChad
03/28/2024, 6:15 AMD_Inventor
03/28/2024, 9:56 AMskttl
03/28/2024, 2:33 PMChad
03/28/2024, 10:11 PMusing System.Security.Cryptography;
using System.Text;
//This has been set to a well known password of "Password123!@#"
var passwordStoredInDatabase = "cPwN11HfULD1FZQYAOFYJg==KAppawBIUf1cpgwspme5pVEVa5xN3A6ZFH2rtt1KWSU=";
//The salt is the first 24 characters of what is stored in the database for the password.
var salt = passwordStoredInDatabase[..24];
var saltBytes = Convert.FromBase64String(salt);
//By default, the KeyLength is 64 bytes, presumably based on the machine key in webconfig
//The following code pads it out based on the provided salt.
//This code is in the Umbraco source, apparently pinched from the SqlMembershipProvider, which has some questionable licensing implications.
var dstOffset = 0;
var newSalt = new byte[64];
while (dstOffset < newSalt.Length)
{
var count = Math.Min(saltBytes.Length, newSalt.Length - dstOffset);
Buffer.BlockCopy(saltBytes, 0, newSalt, dstOffset, count);
dstOffset += count;
}
using var hashAlgorith = new HMACSHA256(newSalt);
//This is what we are trying to match
var passwordBytes = Encoding.Unicode.GetBytes("Password123!@#");
var ourNewPasswordHash = Convert.ToBase64String(hashAlgorith.ComputeHash(passwordBytes));
Console.WriteLine("Resulting hash: {0}", ourNewPasswordHash);
//This is the password component of what is stored in the database. I.e everything that is not the salt.
var hashedPasswordInDatabase = passwordStoredInDatabase[salt.Length..];
Console.WriteLine("Matching password? {0}", ourNewPasswordHash == hashedPasswordInDatabase);