using System.Security.Cryptography; using System.Text; namespace Fitness_core_BE.Helpers { /// /// Generates and hashes agent API keys. The raw key is high-entropy random bytes, /// shown to the agent exactly ONCE at enrollment. Only the SHA-256 hash is persisted /// in Agent.ApiKeyHash, so a leaked database cannot be used to recover usable keys. /// public static class ApiKeyHelper { // 32 bytes = 256 bits of entropy. private const int KeyByteLength = 32; /// /// Generates a new random API key encoded as base64url (URL/header safe, no padding). /// public static string GenerateApiKey() { byte[] bytes = RandomNumberGenerator.GetBytes(KeyByteLength); return ToBase64Url(bytes); } /// /// Hashes a raw API key for storage/lookup. The key is high-entropy so an /// unsalted SHA-256 is sufficient (and deterministic, so we can index/look it up). /// public static string HashApiKey(string apiKey) { byte[] hash = SHA256.HashData(Encoding.UTF8.GetBytes(apiKey)); return Convert.ToBase64String(hash); } private static string ToBase64Url(byte[] bytes) { return Convert.ToBase64String(bytes) .TrimEnd('=') .Replace('+', '-') .Replace('/', '_'); } } }