using System; using System.Linq; using System.Security.Cryptography; using IdentityModel; namespace Kyoo.Authentication { public static class PasswordUtils { /// /// Generate an OneTimeAccessCode. /// /// A new otac. public static string GenerateOTAC() { return CryptoRandom.CreateUniqueId(); } /// /// Hash a password to store it has a verification only. /// /// The password to hash /// The hashed password public static string HashPassword(string password) { byte[] salt = new byte[16]; new RNGCryptoServiceProvider().GetBytes(salt); Rfc2898DeriveBytes pbkdf2 = new(password, salt, 100000); byte[] hash = pbkdf2.GetBytes(20); byte[] hashBytes = new byte[36]; Array.Copy(salt, 0, hashBytes, 0, 16); Array.Copy(hash, 0, hashBytes, 16, 20); return Convert.ToBase64String(hashBytes); } /// /// Check if a password is the same as a valid hashed password. /// /// The password to check /// /// The valid hashed password. This password must be hashed via . /// /// True if the password is valid, false otherwise. public static bool CheckPassword(string password, string validPassword) { byte[] validHash = Convert.FromBase64String(validPassword); byte[] salt = new byte[16]; Array.Copy(validHash, 0, salt, 0, 16); Rfc2898DeriveBytes pbkdf2 = new(password, salt, 100000); byte[] hash = pbkdf2.GetBytes(20); return hash.SequenceEqual(validHash.Skip(16)); } } }