Skip to content
.NET Implementation of PASETO (v2 local / public encryption)
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


.NET Implementation of PASETO

Build status Build Status NuGet contributions welcome

For more information about the standard:


  • 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.



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 = "",
	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 })));
You can’t perform that action at this time.