AgeSharp 0.1.0-preview.1
See the version list below for details.
dotnet add package AgeSharp --version 0.1.0-preview.1
NuGet\Install-Package AgeSharp -Version 0.1.0-preview.1
<PackageReference Include="AgeSharp" Version="0.1.0-preview.1" />
<PackageVersion Include="AgeSharp" Version="0.1.0-preview.1" />
<PackageReference Include="AgeSharp" />
paket add AgeSharp --version 0.1.0-preview.1
#r "nuget: AgeSharp, 0.1.0-preview.1"
#:package AgeSharp@0.1.0-preview.1
#addin nuget:?package=AgeSharp&version=0.1.0-preview.1&prerelease
#tool nuget:?package=AgeSharp&version=0.1.0-preview.1&prerelease
<p align="center"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://github.com/FiloSottile/age/blob/main/logo/logo_white.svg"> <source media="(prefers-color-scheme: light)" srcset="https://github.com/FiloSottile/age/blob/main/logo/logo.svg"> <img alt="The age logo, a wireframe of St. Peters dome in Rome, with the text: age, file encryption" width="600" src="https://github.com/FiloSottile/age/blob/main/logo/logo.svg"> </picture> </p>
AgeSharp is a C# implementation of the
age file encryption format, fully interoperable
with the reference Go implementation and
other age-compatible tools.
It depends only on NSec.Cryptography (which bundles libsodium), and targets .NET 10.
Features
- Simple, streaming API — encrypt and decrypt with a single method call
- X25519 key pairs and scrypt passphrase encryption
- ASCII armor (PEM) support
- Encrypt to multiple recipients
- Extensible via custom
IRecipient/IIdentityimplementations - Interoperable — files produced by AgeSharp can be decrypted by
age,rage, and vice versa - Minimal dependencies — only NSec.Cryptography / libsodium
Installation
dotnet add package AgeSharp
Usage
AgeSharp provides a simple static API in the Age namespace.
Encrypt and decrypt with a new recipient / identity pair
using Age;
using Age.Recipients;
using var identity = X25519Identity.Generate();
var recipient = identity.Recipient;
Console.WriteLine(identity); // AGE-SECRET-KEY-1...
Console.WriteLine(recipient); // age1...
using var input = new MemoryStream("Hello, age!"u8.ToArray());
using var encrypted = new MemoryStream();
AgeEncrypt.Encrypt(input, encrypted, recipient);
encrypted.Position = 0;
using var decrypted = new MemoryStream();
AgeEncrypt.Decrypt(encrypted, decrypted, identity);
Console.WriteLine(Encoding.UTF8.GetString(decrypted.ToArray()));
Encrypt and decrypt with a passphrase
using Age;
using Age.Recipients;
var passphrase = new ScryptRecipient("burst-swarm-slender-curve-ability-various-crystal-moon-affair-three");
using var input = new MemoryStream("Hello, age!"u8.ToArray());
using var encrypted = new MemoryStream();
AgeEncrypt.Encrypt(input, encrypted, passphrase);
encrypted.Position = 0;
using var decrypted = new MemoryStream();
AgeEncrypt.Decrypt(encrypted, decrypted, passphrase);
ASCII armoring
age encrypted files are binary. There is an official ASCII "armor" format, based on PEM, which provides a way to encode an encrypted file as text.
using Age;
using Age.Recipients;
using var identity = X25519Identity.Generate();
using var input = new MemoryStream("Hello, age!"u8.ToArray());
using var encrypted = new MemoryStream();
AgeEncrypt.Encrypt(input, encrypted, armor: true, identity.Recipient);
// -----BEGIN AGE ENCRYPTED FILE-----
// YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA...
// -----END AGE ENCRYPTED FILE-----
Encrypt to multiple recipients
using Age;
using Age.Recipients;
using var alice = X25519Identity.Generate();
using var bob = X25519Identity.Generate();
using var input = new MemoryStream("Hello, everyone!"u8.ToArray());
using var encrypted = new MemoryStream();
AgeEncrypt.Encrypt(input, encrypted, alice.Recipient, bob.Recipient);
// Either identity can decrypt
encrypted.Position = 0;
using var decrypted = new MemoryStream();
AgeEncrypt.Decrypt(encrypted, decrypted, bob);
Parse existing keys
using Age;
var identity = AgeKeygen.ParseIdentity("AGE-SECRET-KEY-1...");
var recipient = AgeKeygen.ParseRecipient("age1...");
Custom recipients and identities
You can implement the IRecipient and IIdentity interfaces to use custom
types as recipients and identities.
using Age.Format;
using Age.Recipients;
public class MyRecipient : IRecipient
{
public Stanza Wrap(ReadOnlySpan<byte> fileKey)
{
// Wrap the file key using your custom scheme
}
}
public class MyIdentity : IIdentity
{
public byte[]? Unwrap(Stanza stanza)
{
// Return the file key if this identity matches, null if not
}
}
This lets you integrate remote APIs, secrets managers, and interoperate with age plugins.
See also
- age-encryption.org/v1 — the age format specification
- age — the reference Go implementation and CLI
- rage — a Rust implementation of age
- awesome-age — a collection of age plugins, tools, and integrations
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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
- NSec.Cryptography (>= 26.1.0-preview.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.2.0-preview.4 | 693 | 7/28/2026 |
| 0.2.0-preview.3 | 692 | 7/23/2026 |
| 0.2.0-preview.2 | 371 | 4/20/2026 |
| 0.2.0-preview.1 | 75 | 4/20/2026 |
| 0.1.0-preview.4 | 94 | 2/25/2026 |
| 0.1.0-preview.3 | 86 | 2/25/2026 |
| 0.1.0-preview.2 | 88 | 2/25/2026 |
| 0.1.0-preview.1 | 86 | 2/24/2026 |