Helper libraries for tokens and cryptography in .NET.
- EdDSA support for JWTs (Ed25519 and Ed448)
- Base16 (hex) and Base62 encoders
passwordrule
attribute support for ASP.NET Identity- Samples in ASP.NET Core
Branca tokens with JWT style validation(deprecated due to low usage of Branca)PASETO (v1.public & v2.public) with JWT style validation(deprecated due to low usage of PASETO)
Feature requests welcome. Please see SECURITY.md for responsible disclosure policy.
EdDSA is a modern signing algorithm that is not yet supported out of the box in .NET. This library provides some useful abstractions around the Bouncy Castle (software) implementation of EdDSA.
// create EdDSA new key pair
EdDsa.Create(ExtendedSecurityAlgorithms.Curves.Ed25519)
// create EdDSA key from parameters
EdDsa.Create(new EdDsaParameters(ExtendedSecurityAlgorithms.Curves.Ed25519)
{D = Base64UrlEncoder.DecodeBytes(privateKey)})
// create EdDSA security key for use with Microsoft.IdentityModel JWT APIs (alg: EdDSA)
new EdDsaSecurityKey(EdDsa.Create(ExtendedSecurityAlgorithms.Curves.Ed25519))
Base16 allows you to encode and decode hexadecimal strings.
var plaintext = "hello world"; // encoded = 68656c6c6f20776f726c64
string encoded = Base16.Encode(Encoding.UTF8.GetBytes(plaintext));
Base62 encoding uses the 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
character set.
var plaintext = "hello world"; // encoded = AAwf93rvy4aWQVw
string encoded = Base62.Encode(Encoding.UTF8.GetBytes(plaintext));
Branca is a token construct suitable for internal systems. The payload is encrypted using XChaCha20-Poly1305, using a 32-byte symmetric key.
This library supports the creation of Branca tokens with an arbitrary payload or using a JWT-style payload.
var handler = new BrancaTokenHandler();
var key = Encoding.UTF8.GetBytes("supersecretkeyyoushouldnotcommit");
// JWT-style payload
string token = handler.CreateToken(new SecurityTokenDescriptor
{
Issuer = "me",
Audience = "you",
Expires = DateTime.UtcNow.AddMinutes(5),
NotBefore = DateTime.UtcNow,
Claims = new Dictionary<string, object> {{"sub", "123"}},
EncryptingCredentials = new EncryptingCredentials(
new SymmetricSecurityKey(key), ExtendedSecurityAlgorithms.XChaCha20Poly1305)
});
ClaimsPrincipal principal = handler.ValidateToken(
token,
new TokenValidationParameters
{
ValidIssuer = "me",
ValidAudience = "you",
TokenDecryptionKey = new SymmetricSecurityKey(key)
}, out SecurityToken parsedToken);
Important
Branca support is now deprecated and only supports Microsoft.IdentityModel 6.35.0. This is due to the low usage of this library and the Branca project as a whole.
PASETO is a competing standard to JOSE & JWT that offers a versioned ciphersuite.
This library currently implements v1
and v2
for the public
purpose, suitable for zero-trust systems such as an OAuth authorization server.
Explicit versioning allows PASETO to side-step attacks on signature validation found in some JWT libraries. However, it does not mitigate any other attacks.
If you are considering using PASETO, I recommend reading RFC 8725 - JWT Best Current Practices and deciding if the interoperable JWT format is still wrong for you.
var handler = new PasetoTokenHandler();
var privateKey = Convert.FromBase64String("TYXei5+8Qd2ZqKIlEuJJ3S50WYuocFTrqK+3/gHVH9B2hpLtAgscF2c9QuWCzV9fQxal3XBqTXivXJPpp79vgw==");
var publicKey = Convert.FromBase64String("doaS7QILHBdnPULlgs1fX0MWpd1wak14r1yT6ae/b4M=");
string token = handler.CreateToken(new PasetoSecurityTokenDescriptor(
PasetoConstants.Versions.V2, PasetoConstants.Purposes.Public)
{
Issuer = "me",
Audience = "you",
Expires = DateTime.UtcNow.AddMinutes(5),
NotBefore = DateTime.UtcNow,
Claims = new Dictionary<string, object> {{"sub", "123"}},
SigningCredentials = new SigningCredentials(
new EdDsaSecurityKey(EdDsa.Create(
new EdDsaParameters(ExtendedSecurityAlgorithms.Curves.Ed25519)
{
D = privateKey
})), ExtendedSecurityAlgorithms.EdDsa)
});
ClaimsPrincipal principal = handler.ValidateToken(
token,
new TokenValidationParameters
{
ValidIssuer = "me",
ValidAudience = "you",
IssuerSigningKey = new EdDsaSecurityKey(EdDsa.Create(
new EdDsaParameters(ExtendedSecurityAlgorithms.Curves.Ed25519) {X = publicKey}))
}, out SecurityToken parsedToken);
Important
PASETO support is now deprecated and only supports Microsoft.IdentityModel 6.35.0. This is due to the low usage of this library and the PASETO project as a whole.
The Branca and PASETO token handlers can be used with the ASP.NET Core JWT bearer authentication handler.
services.AddAuthentication()
.AddJwtBearer("paseto", options =>
{
options.SecurityTokenValidators.Clear();
options.SecurityTokenValidators.Add(new PasetoTokenHandler());
options.TokenValidationParameters.IssuerSigningKey = new EdDsaSecurityKey(EdDSA.Create(<your_public_key>));
options.TokenValidationParameters.ValidIssuer = "you";
options.TokenValidationParameters.ValidAudience = "me";
})