MaskedUUID.AspNetCore
1.0.3
dotnet add package MaskedUUID.AspNetCore --version 1.0.3
NuGet\Install-Package MaskedUUID.AspNetCore -Version 1.0.3
<PackageReference Include="MaskedUUID.AspNetCore" Version="1.0.3" />
<PackageVersion Include="MaskedUUID.AspNetCore" Version="1.0.3" />
<PackageReference Include="MaskedUUID.AspNetCore" />
paket add MaskedUUID.AspNetCore --version 1.0.3
#r "nuget: MaskedUUID.AspNetCore, 1.0.3"
#:package MaskedUUID.AspNetCore@1.0.3
#addin nuget:?package=MaskedUUID.AspNetCore&version=1.0.3
#tool nuget:?package=MaskedUUID.AspNetCore&version=1.0.3
MaskedUUID.AspNetCore
A library for ASP.NET Core that masks the timestamp portion of UUIDv7 using the UUIDv47 algorithm with reversible transformation.
Overview
This library uses UUIDv47Sharp (C# implementation) to reversibly mask GUIDs.
What is UUIDv47?
UUIDv47 is a reversible encoding format that hides the timestamp portion of UUIDv7.
- UUIDv7 → UUIDv47: XOR encryption with a 128-bit key to hide the timestamp
- Reversibility: The original UUIDv7 can be restored from UUIDv47 using the same key
- Key Management: Provide keys via
IMaskedUUIDKeyProvider(flexible support for different keys per tenant, etc.)
Implementations
- uuidv47 - Go implementation (original)
- UUIDv47Sharp - C# implementation
Why use UUIDv47?
UUIDv7 contains a 48-bit timestamp at the beginning, which means exposing it directly reveals the resource creation timestamp.
This poses the following information leakage risks:
- Business information such as user registration time and order time becomes guessable
- Growth rate and new user count leak to the outside
- Business status becomes visible to competitors
This library automatically performs UUIDv7 ↔ UUIDv47 conversion at the following timing:
- API Response:
MaskedGuidtype properties are converted to UUIDv47 when output to JSON - API Request: UUIDv47 strings are automatically restored to the original GUID when received
- URL Parameter: Accept UUIDv47 IDs in URLs like
/items/{id}with automatic restoration - SignalR: Automatic conversion of
MaskedGuidtype properties in Hub send/receive
Specifications (Important)
MaskedGuid Masking Scope
MaskedGuidis masked (encoded/decoded) only during JSON input/output.MaskedGuid.ToString()returns the rawGuidstring (not the masked string).
JSON Serialization Behavior
MaskedGuidusesIMaskedUUIDServicefor masking during JSON conversion.Guid.Empty(empty GUID) becomesnullin JSON output.null/""(empty string) in JSON input is treated asGuid.Empty.
Operation Scope (Within HTTP Request)
- JSON conversion for
MaskedGuidresolvesIMaskedUUIDServicefromHttpContext. - Therefore, JSON serialization/deserialization of
MaskedGuidoutside HTTP requests (background processing, non-Web environments) will throw an exception.
ModelBinder Target
- URL/Query binding targets only
MaskedGuid/MaskedGuid?types. [MaskedUUID]attribute is not used (no attribute-based processing).MaskedGuid?is treated asnullwhen the decode result isGuid.Empty.MaskedGuidremains asGuid.Emptywhen the decode result isGuid.Empty.- In JSON conversion,
Guid.Emptyis output asnulland treated asGuid.Emptywhen read.
- In JSON conversion,
Usage (Overview)
- Register
IMaskedUUIDKeyProvider - Register
IMaskedUUIDService - Add
AddMaskedUUID()andAddMaskedUUIDModelBinder()
See samples/MaskedUUID.Sample for samples.
MVC / API Controllers
// Register KeyProvider (Singleton recommended, Scoped also acceptable)
builder.Services.AddSingleton<IMaskedUUIDKeyProvider, MyKeyProvider>();
// Add MaskedUUID support
builder.Services.AddMaskedUUID();
// Add ModelBinder (for URL/query parameters)
mvcBuilder.AddMaskedUUIDModelBinder();
// Or all at once
mvcBuilder.AddMaskedUUIDControllers();
SignalR
Use the AddMaskedUUID() extension method for SignalR support.
// Register KeyProvider
builder.Services.AddSingleton<IMaskedUUIDKeyProvider, MyKeyProvider>();
// Add MaskedUUID support to SignalR
builder.Services.AddSignalR().AddMaskedUUID();
SignalR Scope Support
SignalR converters resolve services in the following priority order:
- Hub Scope - Scope within Hub invocation (via HubFilter)
- HttpContext Scope - For HTTP connections
- Transient Scope - Fallback
This ensures correct operation whether KeyProvider/Service is Singleton / Scoped / Transient.
Development (Reference Key Usage)
// Use reference keys for development/testing (do not use in production)
builder.Services.AddSignalR().AddMaskedUUIDWithReferenceKeys();
OpenAPI / Swagger
Supports .NET 10+ and .NET 9.
// Add OpenAPI schema transformer
builder.Services.AddOpenApi(options => options.AddMaskedGuidSchemaTransformer());
Automatically handles JsonSchemaType enum in .NET 10+ and string-based type specification in .NET 9.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.AspNetCore.OpenApi (>= 10.0.0)
- UUIDv47Sharp (>= 0.1.1)
-
net9.0
- Microsoft.AspNetCore.OpenApi (>= 9.0.0)
- UUIDv47Sharp (>= 0.1.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.