using System.Security.Cryptography; using System.Text; namespace XFEExtension.NetCore.ServerInteractive.Utilities.Helpers; internal static class SessionTokenHelper { public static string Create(out string tokenHash) { var token = Convert.ToBase64String(RandomNumberGenerator.GetBytes(32)).TrimEnd('=').Replace('+', '-').Replace('/', '_'); tokenHash = Hash(token); return token; } public static string Hash(string token) => Convert.ToBase64String(SHA256.HashData(Encoding.UTF8.GetBytes(token))); public static bool Matches(string token, string storedHash) { try { var actual = SHA256.HashData(Encoding.UTF8.GetBytes(token)); var expected = Convert.FromBase64String(storedHash); return actual.Length == expected.Length && CryptographicOperations.FixedTimeEquals(actual, expected); } catch (FormatException) { return false; } } }