Experimental Python toolkit for reading the French National Identity Card (Carte Nationale d'Identité, CNI) via a PC/SC contact smart card reader, using PACE-CAN authentication and Secure Messaging.
Disclaimer: This project is for educational and research purposes only. Use it solely on cards you own or have explicit permission to read.
Modern French CNIs (issued since 2021) embed a chip that stores biographic data and a facial image in the ICAO LDS (Logical Data Structure) format (ICAO Doc 9303). This toolkit:
- Authenticates to the chip using PACE-CAN (Password Authenticated Connection Establishment with the Card Access Number printed on the card), implemented with BrainpoolP256r1 ECDH + AES-CBC-CMAC-256.
- Establishes a Secure Messaging (SM) session to protect all subsequent exchanges.
- Reads and parses ICAO LDS Data Groups:
- DG1 — MRZ (Machine Readable Zone): document number, name, birth date, nationality, expiry date
- DG2 — Facial image (JPEG / JPEG 2000)
- DG11 / DG12 — Additional personal details (best-effort)
- DG13 — France-specific operator data: address, place of birth, height (best-effort)
- DG14 — Security infos (OID list)
- EF.SOD — Document Security Object: hash verification of all read DGs
- Dumps raw binary EF/DG files and a structured
summary.json.
Biometric data cannot be extracted by this tool. DG3 (fingerprints) and DG4 (iris scan) are protected by Extended Access Control (EAC), a PKI-based protocol that requires a government-issued terminal certificate. Without it, the card returns
6982(security status not satisfied). This tool implements PACE-CAN only and has no EAC support.
- All DGs accessible without EAC are read.
- DG hash verification against EF.SOD is implemented. Full CMS certificate chain verification is not yet implemented.
- DG13 parsing is best-effort, based on the field layout observed on French CNI samples — it is not a universal ICAO standard and may vary across card versions.
- Reading uses short APDUs only, in chunks of
0xE0bytes.
A PC/SC-compatible contact smart card reader is required (e.g. ACS ACR38U, ACS ACR39U, HID Omnikey 3021).
Important: This tool has been tested with a standard contact reader only, not with NFC/contactless readers. While the French CNI chip may be accessible via NFC on some readers, this has not been tested and is not supported.
pyscard requires a PC/SC stack at the OS level.
Fedora / RHEL:
sudo dnf install pcsc-lite pcsc-lite-ccid pcsc-lite-devel swig python3-devel
sudo systemctl enable --now pcscdDebian / Ubuntu:
sudo apt install pcscd libpcsclite-dev swig python3-dev
sudo systemctl enable --now pcscdRequires Python ≥ 3.11.
Using uv (recommended):
git clone https://github.com/YOUR_USERNAME/cnie-python-tools.git
cd cnie-python-tools
uv syncUsing pip:
pip install -e .uv run cnie-dump --out ./dumpThe CAN (6-digit number printed on the front of the card, bottom-right) is prompted interactively with hidden input. It can also be passed directly:
uv run cnie-dump --can 123456 --out ./dump| Option | Description |
|---|---|
--can CAN |
Card Access Number (prompted if omitted) |
--out DIR |
Output directory (default: cnie_dump) |
--trace |
Print raw APDU and SM traces |
--no-sod |
Skip reading EF.SOD |
| File | Content |
|---|---|
ef_com.bin |
Raw EF.COM |
ef_sod.bin |
Raw EF.SOD (if read) |
dg1.bin … dg14.bin |
Raw Data Group files |
dg2_photo.jpg / .jp2 / .j2k |
Extracted facial image |
summary.json |
Parsed structured data |
summary.json includes:
DG1— Parsed MRZ fieldsDG2— Photo extraction statusDG3— Present on the card but not readable without EAC (6982)DG13— Best-effort France-specific fields: height, address, place of birthDG14— List of security OIDs from SecurityInfosSOD— Hash algorithm, per-DG hash values, and verification result
cnie/
├── pcsc.py # PC/SC transport layer
├── pace.py # PACE-CAN (BrainpoolP256r1 ECDH + AES-CBC-CMAC-256)
├── secure_messaging.py # SM session state, DO87/DO97/DO99/DO8E wrapping/unwrapping
├── lds.py # AID selection, EF.COM, EF.SOD, resilient DG reading
├── datagroups.py # DG1/DG2/DG11–DG14 parsers
├── sod.py # EF.SOD hash extraction and DG hash verification
├── apdu.py # APDU helpers
├── crypto.py # Cryptographic primitives
└── tlv.py # BER-TLV parser
- No EAC support — DG3 (fingerprints) and DG4 (iris scan) are protected by EAC (Extended Access Control), a PKI-based protocol requiring a government-issued terminal certificate. These DGs always return
6982and cannot be read by this tool. - No CMS signature verification — EF.SOD embeds a CMS-signed structure with a certificate chain up to the CSCA (Country Signing Certificate Authority). Full chain verification is not yet implemented.
- DG13 is France-specific — Field interpretation is based on observed samples and may be inaccurate for other card generations.
- Contact reader only — NFC/contactless access has not been tested.
- Short APDUs only — APDU command chaining is not used.
- ICAO Doc 9303 — Machine Readable Travel Documents
- BSI TR-03110 — Advanced Security Mechanisms for MRTD (PACE)
MIT — see LICENSE.