.NET Implementation of PASETO
For more information about the standard: https://github.com/paragonie/paseto
- Supports full .NET Framework and .NET Core (Windows / OS X / Linux)
- v2 public authentication (uses Ed25519 signatures)
- v2 local authentication (uses XChaCha20-Poly1305 and Blake2b)
- No dependency on JSON.NET
- Easy token creation and support for raw byte arrays
- This library doesn't support v1 tokens. Per the spec v1 tokens should only be used on systems that can't support modern cryptography.
- Managed Ed25519 implementation from https://github.com/CodesInChaos/Chaos.NaCl
- A fork of libsodium-net is used for XChaCha20-Poly1305
- simple-json for the embedded JSON parser
Install-Package Paseto
Note: If you need a managed-only implementation that does not use libsodium, install
Paseto.Public
, which only supports handling public tokens. If I can find a managed only implementation of XChaCha20-Poly1305, I'll update the main package to reference it.
using Paseto.Authentication;
// Creating a token
var claims = new PasetoInstance
{
Issuer = "http://auth.example.com",
Subject = "2986689",
Audience = "audience",
Expiration = now.AddMinutes(10),
NotBefore = now.AddMinutes(-10),
IssuedAt = now,
AdditionalClaims = new Dictionary<string, object>
{
["roles"] = new[] { "Admin", "User" }
},
Footer = new Dictionary<string, object>
{
["kid"] = "dpm0"
},
};
// Signing and parsing the token with public signing
string token = PasetoUtility.Sign(_publicKey, _privateKey, claims);
var parsedToken = PasetoUtility.Parse(_publicKey, token, validateTimes: true);
Assert.Equal(claims.Subject, parsedToken.Subject);
// Same, but with local encryption
string token = PasetoUtility.Encrypt(_symmetricKey, claims);
var parsedToken = PasetoUtility.Decrypt(_symmetricKey, token, validateTimes: true);
Assert.Equal(claims.Subject, parsedToken.Subject);
// Arbitrary byte array support with public signing
byte[] payload = Encoding.UTF8.GetBytes("Hello Paseto.Net");
string signature = PasetoUtility.SignBytes(_publicKey, _privateKey, payload); // v2.public.signature
Assert.Equal(payload, PasetoUtility.ParseBytes(_publicKey, signature).Payload);
// Same, but with local encryption
byte[] payload = Encoding.UTF8.GetBytes("Hello Paseto.Net");
string encrypted = PasetoUtility.EncryptBytes(_symmetricKey, payload, nonce);
Assert.Equal(payload, PasetoUtility.DecryptBytes(_symmetricKey, encrypted));
// Read footer without decrypting (untrusted data!)
string footerText = "Hello friend";
Assert.Equal(footerText, PasetoUtility.GetFooter(PasetoUtility.EncryptBytes(_symmetricKey, new byte[0], footerText)));
var footerJson = new Dictionary<string, object> { ["key-id"] = "key10" };
Assert.Equal(footerJson, PasetoUtility.GetFooterJson(PasetoUtility.Encrypt(_symmetricKey, new PasetoInstance { Footer = footerJson })));