/// <summary> /// Parses a formatted hash string and extracts the parameters used to /// the create the hash /// </summary> /// public static Params ParseParams(PasswordHashString hashstring) { // Add exceptions for invalid string parameters Params output = new Params(); output.Tau = Tools.EncodeBase64(hashstring.digest); string state = hashstring.stateData; output.Workfactor = Convert.ToUInt32(state.Substring(1, 1)); int wlHigh = Convert.ToInt16(state.Substring(2, 1)); int wlLow = Convert.ToInt16(state.Substring(3, 1)); int wl = 10 * wlHigh + wlLow; output.Workfactor <<= wl; string hashFlag = state.Substring(0, 1); switch (hashFlag) { case "n": output.PreHash = false; output.PostHashLength = 0; break; case "r": output.PreHash = true; output.PostHashLength = 0; break; case "s": output.PreHash = false; output.PostHashLength = (ushort)output.Tau.Length; break; case "b": output.PreHash = true; output.PostHashLength = (ushort)output.Tau.Length; break; default: throw new Exception("invalid Makwa output string"); } return(output); }
/// <summary> /// Verifies a given password against a formatted hash string, function uses /// constant time byte comparison to protect against timing attacks. /// </summary> /// <param name="password">Password to verify</param> /// <param name="hash">A full formatted Makwa hash string</param> /// <returns>A boolean confirmation</returns> public bool VerifyPassword(string password, string hash) { PasswordHashString hashString = new PasswordHashString() { FullHash = hash }; Params hashParams = ParseParams(hashString); if (InvalidModulus(hashString)) { throw new ArgumentException("Password modulus doesnt match Hasher modulus"); } Prehashing = hashParams.PreHash; Posthashing = hashParams.PostHashLength; Workfactor = hashParams.Workfactor; byte[] passwordDigest = Digest(password, hashString.salt); bool match = Tools.ConstantTimeComparison(hashParams.Tau, passwordDigest); return(match); }
/// <summary> /// Confirms the modulus in a formatted hash string matches the /// one currently being used by the hasher /// </summary> bool InvalidModulus(PasswordHashString hashstring) { return(hashstring.modulusChecksum != ModulusChecksum); }