[backend] Replace cuid2 with System.Cryptography-based CSPRNG

This allows us to drop the cuid.net dependency and is ~6x faster while improving security (cuid2 is dubious at best in this regard). We may switch to ULID or UUIDv7 in the future for even higher performance, but this change allows for improving performance and security without any side effects.
This commit is contained in:
Laura Hausmann 2024-05-27 13:27:49 +02:00
parent cc161f1b32
commit d3aed20843
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
3 changed files with 30 additions and 7 deletions

View file

@ -4,7 +4,31 @@ namespace Iceshrimp.Backend.Core.Helpers;
public static class CryptographyHelpers
{
private const string AlphaNumCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
public static string GenerateRandomString(int length) => RandomNumberGenerator.GetString(AlphaNumCharset, length);
public static string GenerateRandomHexString(int length) => RandomNumberGenerator.GetHexString(length, true);
public static string GenerateRandomHexString(int length)
=> RandomNumberGenerator.GetHexString(length, true);
public static string GenerateRandomString(int length, Charset charset = Charset.AlphaNum)
=> RandomNumberGenerator.GetString(GetCharset(charset), length);
public enum Charset
{
AlphaNum,
AlphaNumLower,
CrockfordBase32,
CrockfordBase32Lower
}
private static string GetCharset(Charset charset) => charset switch
{
Charset.AlphaNum => AlphaNumCharset,
Charset.AlphaNumLower => AlphaNumLowerCharset,
Charset.CrockfordBase32 => CrockfordBase32Charset,
Charset.CrockfordBase32Lower => CrockfordBase32LowerCharset,
_ => throw new ArgumentOutOfRangeException(nameof(charset), charset, null)
};
private const string AlphaNumCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private const string AlphaNumLowerCharset = "abcdefghijklmnopqrstuvwxyz0123456789";
private const string CrockfordBase32Charset = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
private const string CrockfordBase32LowerCharset = "0123456789abcdefghjkmnpqrstvwxyz";
}

View file

@ -1,5 +1,4 @@
using Iceshrimp.Backend.Core.Extensions;
using Visus.Cuid;
namespace Iceshrimp.Backend.Core.Helpers;
@ -14,10 +13,11 @@ public static class IdHelpers
createdAt ??= DateTime.UtcNow;
var cuid = new Cuid2(8);
// We want to use a charset with a power-of-two amount of possible characters for optimal CSPRNG performance.
var random = CryptographyHelpers.GenerateRandomString(8, CryptographyHelpers.Charset.CrockfordBase32Lower);
var now = (long)createdAt.Value.Subtract(DateTime.UnixEpoch).TotalMilliseconds;
var time = Math.Max(now - Time2000, 0);
var timestamp = time.ToBase36().PadLeft(8, '0');
return timestamp + cuid;
return timestamp + random;
}
}

View file

@ -33,7 +33,6 @@
<PackageReference Include="AngleSharp" Version="1.1.2" />
<PackageReference Include="AsyncKeyedLock" Version="6.4.2" />
<PackageReference Include="Blurhash.ImageSharp" Version="3.0.0" />
<PackageReference Include="cuid.net" Version="5.0.2" />
<PackageReference Include="dotNetRdf.Core" Version="3.2.6-iceshrimp" />
<PackageReference Include="EntityFrameworkCore.Exceptions.PostgreSQL" Version="8.1.2" />
<PackageReference Include="EntityFrameworkCore.Projectables" Version="3.0.4" />