Eerste commit
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace MijnBesluit.Application.Security;
|
||||
|
||||
/// <summary>
|
||||
/// Genereert uitnodigings- en sessietokens. Alleen de hash gaat de database in;
|
||||
/// het token zelf bestaat maar één keer, in de e-mail of bij de client.
|
||||
/// </summary>
|
||||
public static class TokenGenerator
|
||||
{
|
||||
/// <summary>Nieuw token als URL-veilige base64-tekst.</summary>
|
||||
public static string Create(int byteLength = 32) =>
|
||||
Convert.ToBase64String(RandomNumberGenerator.GetBytes(byteLength))
|
||||
.Replace('+', '-').Replace('/', '_').TrimEnd('=');
|
||||
|
||||
/// <summary>SHA-256 van het token, zoals het in de database wordt bewaard.</summary>
|
||||
public static byte[] HashToken(string token) =>
|
||||
SHA256.HashData(System.Text.Encoding.UTF8.GetBytes(token));
|
||||
|
||||
/// <summary>Vergelijking in constante tijd van een aangeboden token met een opgeslagen hash.</summary>
|
||||
public static bool Matches(string token, byte[] storedHash) =>
|
||||
storedHash.Length == 32 && CryptographicOperations.FixedTimeEquals(HashToken(token), storedHash);
|
||||
|
||||
/// <summary>
|
||||
/// Leidt uit het token zelf een 256-bit sleutel af, los van <see cref="HashToken"/>.
|
||||
///
|
||||
/// Dat "los van" is de reden dat dit een aparte methode is en geen hergebruik van de hash:
|
||||
/// die hash staat in de database om het token te herkennen. Was de afgeleide sleutel
|
||||
/// daaraan gelijk, dan lag de sleutel waarmee een bericht is versleuteld gewoon naast de
|
||||
/// hash in diezelfde database - dat maakt de versleuteling zinloos. <paramref name="doel"/>
|
||||
/// zorgt er bovendien voor dat twee sleutels voor hetzelfde token, voor iets anders
|
||||
/// gebruikt, elkaar niet gelijk zijn.
|
||||
/// </summary>
|
||||
public static byte[] DeriveKey(string token, string doel) =>
|
||||
HMACSHA256.HashData(Encoding.UTF8.GetBytes(token), Encoding.UTF8.GetBytes(doel));
|
||||
}
|
||||
Reference in New Issue
Block a user