Skip to content

Instantly share code, notes, and snippets.

View edamtoft's full-sized avatar

Eric Damtoft edamtoft

View GitHub Profile
@edamtoft
edamtoft / DomainObject.cs
Last active October 24, 2018 21:54
A barebones domain object in C# that wraps a string. Can be converted to and from a string and serialized.
[TypeConverter(typeof(Converter))]
public readonly struct DomainObject : IEquatable<DomainObject>, IEquatable<string>
{
public readonly string _value;
public DomainObject(string value) => _value = value ?? throw new ArgumentNullException(nameof(value));
public bool Equals(DomainObject other) => StringComparer.OrdinalIgnoreCase.Equals(_value, other._value);
public bool Equals(string other) => StringComparer.OrdinalIgnoreCase.Equals(_value, other);
@edamtoft
edamtoft / RateLimitingOptions.cs
Last active November 13, 2018 16:43
Rate Limiting with C# and Redis
public sealed class RateLimitingOptions
{
public int Attempts { get; set; }
public int Seconds { get; set; }
public int RedisDb { get; set; }
}
@edamtoft
edamtoft / keybase.md
Created November 20, 2018 18:08
Keybase Verification

Keybase proof

I hereby claim:

  • I am edamtoft on github.
  • I am edamtoft (https://keybase.io/edamtoft) on keybase.
  • I have a public key ASAW4K_70VpLoPo8TegJ_4-8BBhrH2FxGKoSBEO0cqVYogo

To claim this, I am signing this object:

@edamtoft
edamtoft / IRateLimiter.cs
Last active February 20, 2019 15:52
Rate Limiting for X-Requests-per-Y-Timespan APIs
public interface IRateLimiter
{
Task<T> RunRateLimited<T>(Func<Task<T>> func);
}
@edamtoft
edamtoft / IPasswordHasher.cs
Last active March 27, 2019 18:21
IPasswordHasher Interface
public interface IPasswordHasher
{
string Hash(string password);
(bool Verified, bool NeedsUpgrade) Check(string hash, string password);
}
public sealed class HashingOptions
{
public int Iterations { get; set; } = 10000;
}
public sealed class PasswordHasher : IPasswordHasher
{
private const int SaltSize = 16; // 128 bit
private const int KeySize = 32; // 256 bit
public PasswordHasher(IOptions<HashingOptions> options)
{
Options = options.Value;
}
public string Hash(string password)
{
using (var algorithm = new Rfc2898DeriveBytes(
password,
SaltSize,
Options.Iterations,
HashAlgorithmName.SHA256))
{
var key = Convert.ToBase64String(algorithm.GetBytes(KeySize));
var salt = Convert.ToBase64String(algorithm.Salt);
public (bool Verified, bool NeedsUpgrade) Check(string hash, string password)
{
var parts = hash.Split('.', 3);
if (parts.Length != 3)
{
throw new FormatException("Unexpected hash format. " +
"Should be formatted as `{iterations}.{salt}.{hash}`");
}
@edamtoft
edamtoft / PasswordHasher.cs
Last active September 11, 2021 11:17
Password Hashing in .NET Core - Full Implementation
public sealed class PasswordHasher : IPasswordHasher
{
private const int SaltSize = 16; // 128 bit
private const int KeySize = 32; // 256 bit
public PasswordHasher(IOptions<HashingOptions> options)
{
Options = options.Value;
}