nMRTD 0.4.1-alpha

This is a prerelease version of nMRTD.
dotnet add package nMRTD --version 0.4.1-alpha
                    
NuGet\Install-Package nMRTD -Version 0.4.1-alpha
                    
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="nMRTD" Version="0.4.1-alpha" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="nMRTD" Version="0.4.1-alpha" />
                    
Directory.Packages.props
<PackageReference Include="nMRTD" />
                    
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 nMRTD --version 0.4.1-alpha
                    
#r "nuget: nMRTD, 0.4.1-alpha"
                    
#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 nMRTD@0.4.1-alpha
                    
#: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=nMRTD&version=0.4.1-alpha&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=nMRTD&version=0.4.1-alpha&prerelease
                    
Install as a Cake Tool

nMRTD

NuGet version Target Framework License: LGPL v3

Status: THIS IS AN EARLY-STAGE PORT: the core protocol stack (BAC, PACE, EAC, Active/Passive Authentication) and the LDS/biometric data model are implemented and build cleanly, but the library has not yet been exercised against a broad range of real-world documents or covered by an automated test suite. Treat it as a foundation to build on and validate for your own use case, not as a production-hardened SDK yet.

Please note: this project is AI-assisted.

nMRTD is a .NET 6/8 library for reading electronic Machine Readable Travel Documents (eMRTDs) — biometric passports, electronic ID cards, and similar ICAO-compliant documents — over NFC/contactless smart card readers, implementing the ICAO Doc 9303 specification.

It is a from-scratch C# port of JMRTD, the reference Java implementation of the MRTD standards, targeting .NET 6/8, Native AOT (.NET 8 only), and cross-platform smart card access (Windows, Linux, macOS) via PC/SC.

Features

  • Smart card access layer — a CardService abstraction (command/response APDUs, file system, TLV utilities) with a cross-platform PC/SC implementation (PCSC / PCSC.Iso7816) working over WinSCard on Windows and PC/SC-lite on Linux/macOS.
  • Access-control and secure-messaging protocols:
    • BAC (Basic Access Control), keyed from the MRZ.
    • PACE (Password Authenticated Connection Establishment), keyed either from the MRZ or from the document's CAN (Card Access Number).
    • EAC (Extended Access Control): Chip Authentication and Terminal Authentication (BSI TR-03110), including Card Verifiable (CV) certificate parsing/building.
    • Active Authentication.
    • Secure Messaging (DESede and AES) wrapping every subsequent APDU exchange.
  • LDS (Logical Data Structure) parsing — EF.COM, EF.SOD, and data groups DG1 through DG16 (MRZ, facial/fingerprint/iris images, additional personal/document details, security infos, and more), plus Passive Authentication: verifying each data group's hash and the EF.SOD's CMS/PKCS#7 signature.
  • Biometric data models for both ISO/IEC 19794 (face/finger/iris, the common case) and the newer ISO/IEC 39794 standard, wrapped per CBEFF (ISO/IEC 7816-11).
  • Native AOT and trimming friendly, with no reflection-based dispatch or serialization — built to publish as a self-contained native executable on any of the supported platforms.

Installation

Add the package to your .NET project:

dotnet add package nMRTD

or reference it directly in your .csproj:

<ItemGroup>
  <PackageReference Include="nMRTD" />
</ItemGroup>

nMRTD targets .NET 6/8 and depends on the following transitive dependencies:

Quick start

Reading a document with BAC

using nMRTD;
using nMRTD.Lds.Icao;
using nMRTD.SmartCards;

// Connect to the first available PC/SC reader.
var cardService = new PcscCardService();
var passportService = new PassportService(
    cardService,
    PassportService.NormalMaxTranceiveLength,
    PassportService.DefaultMaxBlocksize,
    isSfiEnabled: true,
    shouldCheckMac: true);

passportService.Open();

// Authenticate with Basic Access Control, keyed from the printed MRZ.
var bacKey = new BacKey(
    documentNumber: "L898902C3",
    dateOfBirth: "740812",   // yyMMdd
    dateOfExpiry: "120415"); // yyMMdd

passportService.SendSelectApplet(false);
passportService.DoBAC(bacKey);

// Read and parse EF.DG1 (the MRZ).
using Stream dg1Stream = passportService.GetInputStream(PassportService.EF_DG1);
var dg1 = new DG1File(dg1Stream);
Console.WriteLine($"Document number: {dg1.GetMRZInfo().GetDocumentNumber()}");

// Read and parse EF.DG2 (the facial image).
using Stream dg2Stream = passportService.GetInputStream(PassportService.EF_DG2);
var dg2 = new DG2File(dg2Stream);

passportService.Close();

Authenticating with PACE, via MRZ or CAN

Most current documents advertise PACE support in EF.CardAccess; prefer it over BAC when available:

using nMRTD;
using nMRTD.Lds;
using nMRTD.SmartCards;

using Stream cardAccessStream = passportService.GetInputStream(PassportService.EF_CARD_ACCESS);
var cardAccessFile = new CardAccessFile(cardAccessStream);
PACEInfo paceInfo = cardAccessFile.GetSecurityInfos().OfType<PACEInfo>().First();

var parameterId = paceInfo.GetParameterId()!;
object staticParameters = PACEInfo.ToParameterSpec(parameterId);

// Option A -- derive the PACE key from the MRZ, same details as for BAC:
IAccessKeySpec paceKey = PaceKeySpec.CreateMrzKey(
    new BacKey("L898902C3", "740812", "120415"));

// Option B -- derive the PACE key from the Card Access Number printed on the
// document instead. A CAN can *only* be used for PACE, never for BAC.
// IAccessKeySpec paceKey = PaceKeySpec.CreateCanKey("500540");

passportService.DoPace(paceKey, paceInfo.GetObjectIdentifier(), staticParameters, parameterId);
passportService.SendSelectApplet(true);

// From here on, read DG1/DG2/... exactly as in the BAC example above.

For a complete, runnable example covering reader selection, PACE-with-BAC-fallback, DG1/DG2 parsing, and full Passive Authentication (EF.SOD hash and signature verification), see nMRTD.Cli/Program.cs in this repository.

License

nMRTD is a derivative work: a from-scratch C# port of JMRTD, originally written in Java by the JMRTD team. All credit for the original design, protocol implementation, and years of ICAO 9303 domain expertise belongs to them; this project would not exist without their work. nMRTD is not affiliated with or endorsed by the JMRTD project.

Like its upstream, nMRTD is distributed under the terms of the GNU Lesser General Public License v3 (LGPL-3.0). See the LICENSE file for the full license text.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  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 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.

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.1-alpha 67 9/1/2026
0.4.0-alpha 61 9/1/2026
0.3.0-alpha 71 8/26/2026
0.2.0-alpha 67 8/23/2026