RustPdf 0.4.5

There is a newer version of this package available.
See the version list below for details.
dotnet add package RustPdf --version 0.4.5
                    
NuGet\Install-Package RustPdf -Version 0.4.5
                    
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="RustPdf" Version="0.4.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RustPdf" Version="0.4.5" />
                    
Directory.Packages.props
<PackageReference Include="RustPdf" />
                    
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 RustPdf --version 0.4.5
                    
#r "nuget: RustPdf, 0.4.5"
                    
#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 RustPdf@0.4.5
                    
#: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=RustPdf&version=0.4.5
                    
Install as a Cake Addin
#tool nuget:?package=RustPdf&version=0.4.5
                    
Install as a Cake Tool

RustPdf (.NET binding)

Idiomatic C#/.NET binding for the rust-pdf core over its C ABI (libpdf_ffi), using source-generated P/Invoke (LibraryImport). It mirrors the full product surface: vector graphics, embedded/subsetted fonts and text, wrapping paragraphs, images, PDF/A (levels 1b–3a), tagged/accessible output, embedded-file attachments, AcroForm fields, manipulation (merge/split/rotate/optimize/incremental update), text extraction, page rendering (page to PNG image), encryption (RC4 / AES-128 / AES-256) and digital signatures (PKCS#7 / PAdES) — plus feature licensing.

Layout:

  • RustPdf/Native.cs — raw P/Invoke (1:1 with include/pdf.h) + a native-library resolver;
  • RustPdf/Document.cs, EditableDoc.csIDisposable wrappers with fluent, exception-based APIs;
  • RustPdf/Pdf.cs — static helpers (Version, ActivateLicense, ExtractText, Sign, Timestamp, AddDss) and the PdfaLevel / Align / AFRelationship / Encryption enums.

Install

dotnet add package RustPdf

The NuGet package bundles the native libpdf_ffi for every supported runtime (osx-arm64, linux-x64, linux-arm64, win-x64) under runtimes/<rid>/native/. .NET's runtime resolves the matching one automatically — no native build, no extra setup.

Loading the native library

For a published package the native lib is resolved from the package's runtimes/<rid>/native/ (the standard NuGet RID-asset convention). For local development against the repo build tree, Native.cs falls back to resolving libpdf_ffi in this order:

  1. RUSTPDF_LIB (explicit path);
  2. by walking up from the assembly directory looking for target/{debug,release}/libpdf_ffi.* (local build tree);
  3. the platform default search path (e.g. a library shipped next to the app).

Build it from the repo root with cargo build -p pdf-ffi.

Distribution

Published to NuGet.org as the single package RustPdf that carries all four platforms' cdylibs. CI (.github/workflows/release-csharp.yml, trigger csharp-v*) fans out one build job per RID (Linux in manylinux_2_28, macOS arm64, Windows x64 — all with the production license pubkey), then a pack job stages each lib into runtimes/<rid>/native/, runs dotnet pack, and pushes via NuGet Trusted Publishing (OIDC — no long-lived API key). A free-surface smoke (bindings/csharp/Smoke) verifies each platform's lib loads.

Quick start

using RustPdf;

// A token via the RUSTPDF_LICENSE env var is auto-activated; or:
Pdf.ActivateLicense(token);

using (var doc = new Document())
{
    doc.Pdfa(PdfaLevel.A2a).SetInfo(title: "Report", author: "me");
    int f = doc.AddFontFile("assets/fonts/Roboto-Regular.ttf");
    doc.AddPage();
    doc.ShowText(f, 20, 72, 760, "Title", headingLevel: 1);
    doc.Paragraph(f, 12, 72, 720, 450, "A wrapping, justified body…", Align.Justify);
    byte[] data = doc.ToBytes();

    Console.WriteLine(Pdf.ExtractText(data));

    using var ed = EditableDoc.Load(data);     // manipulate + encrypt
    ed.SetInfo("Subject", "Edited");
    ed.Encrypt(owner: "owner", method: Encryption.Aes256);
    ed.Save("secured.pdf");

    byte[] signed = Pdf.Sign(data, keyDer, certDer, reason: "Approved", pades: true);
}

Corporate features (PDF/A, signing, encryption, accessibility, page rendering) require a license; without one they throw PdfException. Page rendering is a Pro feature. See docs/LICENSING.md.

Deferred / HSM signing (key never enters the library)

When the private key lives in an HSM, a cloud KMS, a smartcard or a PKI token (any PKI — eIDAS, AATL, a national CA), the library never sees it: you provide the signature, the library builds the CMS/PKCS#7 container and embeds it. Use this for hardware-backed or remote signing of any kind.

Model A — remote signer callback. The library prepares the signed attributes and calls you back for the raw RSA PKCS#1 v1.5 signature over their SHA-256 digest:

using RustPdf;

byte[] pdf     = File.ReadAllBytes("contract.pdf");
byte[] certDer = File.ReadAllBytes("signer-cert.der");   // X.509 (DER), key stays remote

byte[] signed = Pdf.SignWith(pdf, certDer,
    signHash: dataToSign => hsm.SignRsaPkcs1Sha256(dataToSign),   // call your HSM / KMS / token
    chain: new[] { intermediateDer },
    options: new SigningOptions { Reason = "Approved", Pades = true });

File.WriteAllBytes("contract.signed.pdf", signed);

Prefer an interface? Implement IRemoteSigner.SignHash and pass the instance to the same SignWith overload.

Model B — two-phase (async / detached) signing. Phase 1 prepares the PDF and hands you the bytes to sign; do the remote signing out of band; phase 2 embeds the finished container:

SigningSession session = Pdf.BeginSigning(pdf,
    new SigningOptions { Name = "Jane Doe", ContainerSize = 16384 });

byte[] cmsDer = await BuildCmsWithRemoteSignatureAsync(session.Hash);  // SHA-256 of the covered bytes

byte[] signed = session.Complete(cmsDer);            // or Pdf.CompleteSignature(session.Document, cmsDer)

Inspect existing signature fields before signing with Pdf.ListSignatures(pdf) (an empty list means the document is unsigned). SigningOptions also carries Certify (DocMDP certification) and Policy (SignaturePolicy for PAdES-EPES). Raise ContainerSize when a cloud-HSM CMS container is larger than the default 8 KB reservation.

Build & run the sample

cargo build -p pdf-ffi
dotnet run --project bindings/csharp/Sample          # exercises the whole surface

Targets net8.0 (works on .NET 8+); the source-generated P/Invoke needs C# 11+.

Product Compatible and additional computed target framework versions.
.NET 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 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

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.4.8 126 7/2/2026
0.4.6 124 6/30/2026
0.4.5 115 6/30/2026
0.4.4 116 6/30/2026
0.4.3 117 6/29/2026
0.4.2 119 6/29/2026
0.4.1 120 6/29/2026
0.4.0 114 6/29/2026
0.2.0 103 6/28/2026
0.1.0 117 6/27/2026