private bool ValidateCore(string token, Guid userId, ContactChallengePurpose purpose, string stamp) { try { byte[] unprotectedData = Protector.Unprotect(Convert.FromBase64String(token)); var ms = new MemoryStream(unprotectedData); using (var reader = new BinaryReader(ms, DefaultEncoding, true)) { DateTimeOffset creationTime = new DateTimeOffset(reader.ReadInt64(), TimeSpan.Zero); DateTimeOffset expirationTime = creationTime + TokenLifespan; if (expirationTime < DateTimeOffset.UtcNow) { return false; } string tokenUserId = reader.ReadString(); if (!string.Equals(tokenUserId, userId.ToString(), StringComparison.OrdinalIgnoreCase)) { return false; } var tokenPurpose = reader.ReadString(); if (!string.Equals(tokenPurpose, purpose.ToString())) { return false; } var tokenStamp = reader.ReadString(); if (reader.PeekChar() != -1) { return false; } bool isTokenValid = tokenStamp == stamp; return isTokenValid; } } catch { // do not leak exception return false; } }
private string GenerateCore(Guid userId, ContactChallengePurpose purpose, string stamp) { MemoryStream memoryStream = new MemoryStream(); using (var writer = new BinaryWriter(memoryStream, DefaultEncoding, true)) { writer.Write(DateTimeOffset.UtcNow.Ticks); writer.Write(userId.ToString()); writer.Write(purpose.ToString()); writer.Write(stamp); } byte[] protectedBytes = Protector.Protect(memoryStream.ToArray()); string token = Convert.ToBase64String(protectedBytes); return token; }