AsicSharp 1.1.0

dotnet add package AsicSharp --version 1.1.0
                    
NuGet\Install-Package AsicSharp -Version 1.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AsicSharp" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AsicSharp" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="AsicSharp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AsicSharp --version 1.1.0
                    
#r "nuget: AsicSharp, 1.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AsicSharp@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AsicSharp&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=AsicSharp&version=1.1.0
                    
Install as a Cake Tool

AsicSharp

CI NuGet License: MIT

Create and verify ASiC-S and ASiC-E (Associated Signature Containers) with RFC 3161 timestamps in .NET.

Prove that data existed at a specific point in time using trusted Timestamp Authorities (TSA) like DigiCert — without needing your own signing certificate.

What is this?

ASiC containers are ZIP files (per ETSI EN 319 162) that bundle your files with cryptographic timestamps:

  • ASiC-S (Simple) — A single file with a timestamp token
  • ASiC-E (Extended) — Multiple files with an ASiCManifest XML listing each file's digest, timestamped together

This proves that this exact data existed at this exact time, signed by a trusted third party. The format is recognized by the EU eIDAS regulation for legal validity.

Installation

Library (for your application)

dotnet add package AsicSharp

CLI Tool (global)

dotnet tool install -g AsicSharp.Cli

Quick Start

Library Usage

using AsicSharp.Configuration;
using AsicSharp.Services;

// Standalone (no DI)
using var httpClient = new HttpClient();
var options = new AsicTimestampOptions
{
    TimestampAuthorityUrl = WellKnownTsa.DigiCert
};

var tsaClient = new TsaClient(httpClient, options);
var asicService = new AsicService(tsaClient, options);

// Create a timestamped container (single file → ASiC-S)
var data = File.ReadAllBytes("contract.pdf");
var result = await asicService.CreateAsync(data, "contract.pdf");

File.WriteAllBytes("contract.pdf.asics", result.ContainerBytes);
Console.WriteLine($"Timestamped at: {result.Timestamp:O}");

// Create an ASiC-E container (multiple files)
var files = new List<(string FileName, byte[] Data)>
{
    ("contract.pdf", File.ReadAllBytes("contract.pdf")),
    ("annex.pdf", File.ReadAllBytes("annex.pdf"))
};
var extended = await asicService.CreateExtendedAsync(files);
File.WriteAllBytes("bundle.asice", extended.ContainerBytes);

// Verify any container (auto-detects ASiC-S or ASiC-E)
var verification = asicService.VerifyFile("contract.pdf.asics");
Console.WriteLine($"Valid: {verification.IsValid}");
Console.WriteLine($"Timestamp: {verification.Timestamp:O}");
Console.WriteLine($"TSA: {verification.TsaCertificate?.Subject}");

// Renew timestamp for long-term archival (adds archive timestamp per ETSI EN 319 162-1 §5.4)
var renewed = await asicService.RenewFileAsync("contract.pdf.asics");
File.WriteAllBytes("contract.pdf.asics", renewed.ContainerBytes);
Console.WriteLine($"Renewed at: {renewed.Timestamp:O}");

With Dependency Injection

// In Startup / Program.cs
builder.Services.AddAsicSharp(options =>
{
    options.TimestampAuthorityUrl = WellKnownTsa.DigiCert;
    options.HashAlgorithm = HashAlgorithmName.SHA256;
});

// Or bind from configuration
builder.Services.AddAsicSharp(
    builder.Configuration.GetSection("AsicTimestamp"));
// appsettings.json
{
  "AsicTimestamp": {
    "TimestampAuthorityUrl": "http://timestamp.digicert.com",
    "HashAlgorithm": "SHA256",
    "RequestSignerCertificates": true,
    "Timeout": "00:00:30",
    "MaxFileSize": 10485760
  }
}

File size limit: By default, files larger than 10 MB are rejected to prevent accidental memory exhaustion. Set MaxFileSize to a higher value or null to disable the limit.

// In your service
public class MyService
{
    private readonly IAsicService _asicService;

    public MyService(IAsicService asicService)
    {
        _asicService = asicService;
    }

    public async Task TimestampDocument(byte[] data, string fileName)
    {
        var result = await _asicService.CreateAsync(data, fileName);
        // result.ContainerBytes, result.Timestamp, result.DataHash
    }
}

CLI Usage

# Timestamp a single file (ASiC-S)
asicts stamp contract.pdf
asicts stamp contract.pdf --tsa http://timestamp.digicert.com --algorithm SHA256

# Timestamp multiple files (ASiC-E)
asicts stamp contract.pdf annex.pdf terms.txt

# Verify a container (auto-detects ASiC-S or ASiC-E)
asicts verify contract.pdf.asics
asicts verify bundle.asice --verbose

# Renew timestamp for long-term archival
asicts renew contract.pdf.asics
asicts renew bundle.asice --tsa http://timestamp.sectigo.com

# Extract files from any container
asicts extract contract.pdf.asics --output ./extracted/
asicts extract bundle.asice --output ./extracted/

# List known TSA servers
asicts info

Supported Platforms

Target Status
.NET 10.0
.NET 8.0
.NET Standard 2.1 ✅ (.NET Core 3.0+)

Well-Known Timestamp Authorities

TSA URL Notes
DigiCert http://timestamp.digicert.com Default, widely trusted
Sectigo http://timestamp.sectigo.com Formerly Comodo
GlobalSign http://timestamp.globalsign.com/tsa/r6advanced1
FreeTSA https://freetsa.org/tsr Free & open
Apple http://timestamp.apple.com/ts01
Entrust http://timestamp.entrust.net/TSS/RFC3161sha2TS

Container Formats

ASiC-S (Simple) — Single File

document.pdf.asics (ZIP)
├── mimetype                          → "application/vnd.etsi.asic-s+zip"
├── document.pdf                      → Your original file (unchanged)
└── META-INF/
    ├── timestamp.tst                 → RFC 3161 timestamp token (covers the data file)
    ├── timestamp-002.tst             → (After renewal) Archive timestamp covering timestamp.tst
    └── signature.p7s                 → (Optional) CMS/CAdES signature

ASiC-E (Extended) — Multiple Files

bundle.asice (ZIP)
├── mimetype                          → "application/vnd.etsi.asic-e+zip"
├── contract.pdf                      → Data file 1
├── annex.pdf                         → Data file 2
└── META-INF/
    ├── ASiCManifest.xml              → Lists all files with their digests
    ├── timestamp.tst                 → RFC 3161 timestamp token (covers the manifest)
    ├── timestamp-002.tst             → (After renewal) Archive timestamp covering timestamp.tst
    └── signature.p7s                 → (Optional) CMS/CAdES signature

The timestamp in ASiC-E covers the ASiCManifest XML, which in turn contains cryptographic digests of every data file — so all files are transitively timestamped.

Timestamp Renewal for Long-Term Archival

Timestamp tokens have a validity period tied to the TSA certificate's lifetime (typically 5-10 years). For long-term archival, renew the timestamp before the original TSA certificate expires. Per ETSI EN 319 162-1 §5.4, each archive timestamp covers the previous token's bytes, creating a chain:

timestamp.tst      → Covers data (or manifest)
timestamp-002.tst  → Covers timestamp.tst bytes
timestamp-003.tst  → Covers timestamp-002.tst bytes

Verification walks the full chain, ensuring each link is valid. The original timestamp proves when the data existed; renewal timestamps extend the proof indefinitely.

Optional: Signing with Your Own Certificate

If you need to prove who timestamped the data (not just when), provide a signing certificate:

services.AddAsicSharp(options =>
{
    options.SigningCertificate = new X509Certificate2("cert.pfx", "password");
});

This adds a CMS/CAdES detached signature (META-INF/signature.p7s) alongside the timestamp.

Verification Details

The Verify method returns detailed step-by-step results:

var result = asicService.Verify(containerBytes);

foreach (var step in result.Steps)
{
    Console.WriteLine($"{(step.Passed ? "✓" : "✗")} {step.Name}: {step.Detail}");
}
// ✓ Container structure: Valid ZIP archive
// ✓ MIME type: application/vnd.etsi.asic-s+zip
// ✓ Data file: contract.pdf (125432 bytes)
// ✓ Timestamp token decode: Token decoded, timestamp: 2026-02-28T14:30:00Z
// ✓ Timestamp signature: Valid, signed by: CN=DigiCert Timestamp 2024, O=DigiCert
// ✓ Data hash match: Hash in timestamp matches data file

Standards Compliance

  • ETSI EN 319 162-1 — Associated Signature Containers (ASiC) baseline (ASiC-S)
  • ETSI EN 319 162-2 — Associated Signature Containers extended (ASiC-E)
  • ETSI TS 102 918 — ASiCManifest XML schema
  • RFC 3161 — Internet X.509 PKI Time-Stamp Protocol
  • RFC 5652 — Cryptographic Message Syntax (CMS)
  • EU eIDAS Regulation — Electronic identification and trust services

License

MIT — see LICENSE

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  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. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.1.0 70 2/28/2026
1.0.0 79 2/28/2026
0.9.0 77 2/28/2026