Go library for reading Machine Readable Travel Documents (MRTDs) such as passports and identity cards, as specified by ICAO Doc 9303.
This library focuses on NFC protocol handling, access control, LDS parsing, and cryptographic security checks, including passive authentication and chip authentication where supported.
Higher-level concerns such as OCR and UI are intentionally left to the integrator.
gmrtd provides low-level building blocks for reading and authenticating eMRTDs:
- Access Control (BAC and PACE)
- Secure messaging and APDU handling
- LDS parsing (EF.COM, EF.SOD, Data Groups)
- Passive Authentication (SOD verification)
- Chip Authentication (where supported)
- Extended-length APDU support
The library is transport-agnostic and can be used with desktop, mobile, or embedded NFC stacks.
- Legacy access control mechanism
- MRZ-based key derivation only
- Used by older passports and some current documents
- Automatically selected when PACE is not available
- Supported as specified in ICAO Doc 9303
- Strong, modern access control mechanism
- Supported password types:
- MRZ (Machine Readable Zone)
- CAN (Card Access Number), commonly used by modern ID cards
- Supports multiple PACE variants:
- ECDH (GM / CAM)
- AES / 3DES
- Brainpool and secp elliptic curves
The caller supplies either MRZ or CAN; gmrtd negotiates and executes the appropriate protocol automatically based on document capabilities.
- โ BAC (MRZ)
- โ PACE-GM/CAM (MRZ and CAN)
- โ Secure messaging
- โ LDS parsing (EF.COM, EF.SOD, DGs)
- โ Passive Authentication (SOD verification)
- โ Chip Authentication (document-dependent)
- โ Extended-length APDU support
- โ Transport-agnostic design
- โ Terminal Authentication (TA) not implemented
- โ PACE-IM not implemented
- โ No OCR or MRZ extraction
- โ Personal data handling and storage are the responsibility of the caller
A PC/SC demo reader is included in this repository as a Go command: cmd/gmrtd-reader.
It:
- Connects to the first available PC/SC reader
- Runs PACE by default (unless
--skipPaceis set) - Reads and verifies the document (including passive authentication)
- Renders a HTML report (APDU logs + parsed LDS) and opens it in your browser
go run ./cmd/gmrtd-reader --helpgo run ./cmd/gmrtd-reader --doc <DOCUMENT_NUMBER> --dob <YYMMDD> --exp <YYMMDD>go run ./cmd/gmrtd-reader --can <CAN># enable debug logging
--debug
# set/cap maximum Le / read size (bytes)
--maxRead 4096
# skip PACE negotiation (forces BAC where possible; mostly for debugging)
--skipPaceNotes:
--doc/--dob/--expand--canare mutually exclusive.- Requires a PC/SC-compatible NFC reader and a working PC/SC stack.
A command-line utility for auditing the built-in CSCA trust stores is included at cmd/gmrtd-csca.
It lists every CSCA and link certificate across all bundled trust stores, grouped by country, showing key type, validity period, SKI/AKI, and which source(s) each certificate appears in. Broken link certificates (whose parent CSCA is absent from the master lists) are flagged separately.
No NFC hardware is required โ useful for trust-store audits before shipping.
go run ./cmd/gmrtd-cscaThe following documents have been successfully read using gmrtd:
| Country (Type,Year) |
PACE | Chip Authentication | Ext Len |
LDS Ver |
|---|---|---|---|---|
| ๐ฆ๐บ Australia (P,2016) |
n/a (BAC) | AA-rsaEncryption | Yes | 0107 |
| ๐ฆ๐น Austria (P,2023) |
PACE-ECDH-GM-AES-CBC-CMAC-128 brainpoolP256r1 |
CA-ECDH-AES-CBC-CMAC-128 brainpoolP256r1 |
Yes | 0107 |
| ๐จ๐ฆ Canada (PP,2023) |
PACE-ECDH-GM-AES-CBC-CMAC-128 secp384r1 |
CA-ECDH-AES-CBC-CMAC-128 secp384r1 |
No | 0108 |
| ๐จ๐ณ China (PO,2018) |
n/a (BAC) | AA-rsaEncryption | No | 0107 |
| ๐ซ๐ฎ Finland (I,2023) |
PACE-ECDH-GM-AES-CBC-CMAC-256 brainpoolP384r1 |
PACE-ECDH-CAM-AES-CBC-CMAC-256 brainpoolP384r1 |
Yes | 0108 |
| ๐ซ๐ฎ Finland (P,2024) |
PACE-ECDH-GM-AES-CBC-CMAC-256 brainpoolP384r1 |
PACE-ECDH-CAM-AES-CBC-CMAC-256 brainpoolP384r1 |
Yes | 0108 |
| ๐ซ๐ท France (P,2017) |
PACE-ECDH-GM-AES-CBC-CMAC-256 secp256r1 |
CA-ECDH-3DES-CBC-CBC secp256r1 |
Yes | 0107 |
| ๐ซ๐ท France (ID,2024) |
PACE-ECDH-GM-AES-CBC-CMAC-256 brainpoolP256r1 PACE-ECDH-IM-AES-CBC-CMAC-256 brainpoolP256r1 (PACE-IM not supported) |
CA-ECDH-AES-CBC-CMAC-256 brainpoolP256r1 |
Yes | 0108 |
| ๐ฉ๐ช Germany (P,2023) |
PACE-ECDH-GM-AES-CBC-CMAC-128 brainpoolP256r1 |
PACE-ECDH-CAM-AES-CBC-CMAC-128 brainpoolP256r1 CA-ECDH-AES-CBC-CMAC-128 brainpoolP256r1 |
Yes | 0108 |
| ๐ญ๐ฐ Hong Kong (China) (P,2025) |
PACE-ECDH-GM-AES-CBC-CMAC-256 brainpoolP256r1 |
AA-ecc brainpoolP256r1 |
Yes | 0108 |
| ๐ฎ๐ฉ Indonesia (P,2025) โน๏ธ 2010 CSCA Series |
PACE-ECDH-GM-AES-CBC-CMAC-256 brainpoolP256r1 |
CA-ECDH-AES-CBC-CMAC-256 brainpoolP256r1 |
Yes | 0107 |
| ๐ฒ๐พ Malaysia (P,2023) |
n/a (BAC) | CA-ECDH-3DES-CBC-CBC brainpoolP256r1 |
Yes | 0107 |
| ๐ณ๐ฑ Netherlands (PP,2025) |
PACE-ECDH-GM-AES-CBC-CMAC-256 brainpoolP320r1 |
CA-ECDH-AES-CBC-CMAC-256 brainpoolP512r1 |
Yes | 0108 |
| ๐ณ๐ฟ New Zealand (P,2017) |
PACE-ECDH-GM-3DES-CBC-CBC brainpoolP256r1 |
AA-rsaEncryption | No | 0107 |
| ๐ต๐ญ Philippines (P,2020) |
n/a (BAC) | AA-rsaEncryption | Yes | 0107 |
| ๐ต๐น Portugal (PP,2026) |
PACE-ECDH-GM-AES-CBC-CMAC-128 brainpoolP256r1 |
CA-ECDH-AES-CBC-CMAC-128 brainpoolP256r1 |
Yes | 0107 |
| ๐ท๐บ Russia (P,2020) |
n/a (BAC) | CA-ECDH-3DES-CBC-CBC secp192 |
Yes | 0107 |
| ๐ธ๐ฌ Singapore (PA,2023) |
PACE-ECDH-GM-AES-CBC-CMAC-256 brainpoolP256r1 |
Yes | 0108 | |
| ๐ธ๐ฌ Singapore (PP,2025) |
PACE-ECDH-GM-AES-CBC-CMAC-256 brainpoolP256r1 |
AA-rsaEncryption | Yes | 0108 |
| ๐น๐ผ Taiwan (P,2024) |
PACE-ECDH-GM-AES-CBC-CMAC-256 secp256r1 |
Yes | 0107 | |
| ๐ฌ๐ง United Kingdom (P,2021) |
PACE-ECDH-GM-AES-CBC-CMAC-256 secp256r1 |
CA-ECDH-AES-CBC-CMAC-256 secp256r1 |
Yes | 0108 |
| ๐บ๐ธ United States (P,2021) |
n/a (BAC) | No | 0107 |
Notes:
- PACE entries may use MRZ or CAN depending on document type.
- Cloneable reflects the documentโs chip feature set, not a gmrtd vulnerability.
Some MRTDs do not implement strong cryptographic anti-cloning mechanisms (notably Chip Authentication (CA) or Active Authentication (AA)). In these cases:
- Chip data is protected only by access control (BAC or PACE) and secure messaging
- If the access secret (MRZ/CAN) is obtained and the chip is read once, data can be copied and replayed
- This is a document issuer design choice, not a vulnerability in gmrtd
Cloneability does not imply that the physical document can be trivially forged.
For convenience and interoperability testing, gmrtd includes built-in CSCA trust anchors sourced from:
Together these cover 121 countries. These defaults can be replaced, extended, or disabled depending on your trust model.
- Go: 1.19+
- Transports: PC/SC, Core NFC, Android NFC, custom APDU transceivers
- Platforms: Desktop, mobile, embedded
This library is intended for legitimate, consent-based MRTD reading.
Handle personal data in accordance with applicable laws and regulations.
Issues and pull requests are welcome.
When reporting document compatibility issues:
- Do not upload personal data
- Include document type/year, protocol used, and anonymised logs
Made with contrib.rocks.