piv-smartcard
A cross-platform Python library to read X.509 certificates from PIV smart cards over PC/SC (Windows, macOS and Linux).
It is a Python port of GoogleChromeLabs/web-smartcard-demo.
The original is a ChromeOS-only Isolated Web App that uses the experimental
Web Smart Card API to read the X.509 Card Authentication certificate from a
PIV smart card. That API does not exist on Windows or macOS, so this project keeps
the same architecture but talks to the native PC/SC stack through
pyscard, which works on Windows, macOS and Linux.
Architecture
This project (src/smartcard_demo/) |
Original (src/) |
Responsibility |
|---|---|---|
apdu.py |
apdu.ts |
APDU command/response serialization |
ber.py |
ber.ts |
BER-TLV decoding |
piv.py |
piv.ts |
PIV applet: SELECT + read certificate |
util.py |
util.ts |
hex helpers, X.509 parsing, card ID |
reader.py |
Web Smart Card API | PC/SC reader connect / transmit / disconnect |
app.py |
index.ts + .html |
Tkinter UI (Connect / Disconnect / Read) |
cli.py |
— | Command-line interface |
tests/ |
tests/, *.test.ts |
Unit tests (no hardware needed) |
Reader (PC/SC)
│ pyscard (WinSCard on Windows, PCSC framework on macOS)
▼
CardSession ── transmit(CommandAPDU) ──► ResponseAPDU
│
▼
piv.select() ─► piv.read_certificate() ─► BER-TLV decode ─► X.509 parse
│
▼
Tkinter GUI / CLI
Prerequisites
- Python 3.10+
- A smart-card reader and a PIV card (e.g. a YubiKey with the PIV interface).
- Windows: the Smart Card service is built in — nothing to install.
- macOS: the PCSC framework is built in — nothing to install.
- Linux: install
pcscdandlibpcsclite(sudo apt install pcscd libpcsclite-dev).
Install
From PyPI (once published):
pip install piv-smartcard
From source (development):
python -m venv .venv
.venv\Scripts\Activate.ps1 # Windows
# source .venv/bin/activate # macOS / Linux
pip install -e ".[dev]"
Use as a library
from smartcard_demo import CardSession, list_readers, select, read_certificate
reader = list_readers()[0]
with CardSession(reader) as session:
select(session) # SELECT the PIV application
info = read_certificate(session, "card_authentication")
print(info.as_lines())
print(info.pem)
The pure-Python parts (CommandAPDU, BER-TLV parse/find,
parse_certificate, identify_card, SLOTS, ...) are importable without
pyscard; the CardSession / list_readers reader symbols are loaded lazily
and only require pyscard when actually used.
Run the apps
GUI:
piv-smartcard-gui # after install
python main.py # from a source checkout
CLI:
piv-smartcard list
piv-smartcard read
piv-smartcard read --slot authentication --pem
# or, from a source checkout without installing:
python -m smartcard_demo.cli list
PIV certificate slots
| Slot key | Key ref | Object id | Purpose |
|---|---|---|---|
authentication |
9A |
5F C1 05 |
PIV Authentication |
signature |
9C |
5F C1 0A |
Digital Signature |
key_management |
9D |
5F C1 0B |
Key Management |
card_authentication |
9E |
5F C1 01 |
Card Authentication (default) |
Tests
pip install pytest cryptography
pytest
The tests use canned APDU responses and a synthetic certificate, so they run without a reader or card.
Publishing
Build and check the distribution locally:
python -m pip install build twine
python -m build
python -m twine check dist/*
Releasing to PyPI is automated: create a Git tag vX.Y.Z (or publish a GitHub
Release) and the Publish to PyPI workflow builds and uploads via PyPI
Trusted Publishing (OIDC, no token
stored). Configure the trusted publisher once on PyPI, pointing at
amandeepsdet/piv-smartcard and the publish.yml workflow.
git tag v0.1.0
git push origin v0.1.0
Troubleshooting
pyscardfails to build on install (e.g. "Microsoft Visual C++ 14.0 or greater is required"):pyscardships prebuilt wheels only for released Python versions. On very new interpreters (e.g. Python 3.14) pip falls back to compiling from source. Either use Python 3.10–3.13 (recommended), or install the Microsoft C++ Build Tools. Theapdu,ber,utilandpivmodules do not importpyscard, so the test suite runs even whenpyscardis not installed.
Metadata
Release files for piv-smartcard 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| piv_smartcard-0.1.0.tar.gz | 19.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| piv_smartcard-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.2 kB
Release files / piv_smartcard-0.1.0.tar.gz
| Download URL | piv_smartcard-0.1.0.tar.gz |
|---|---|
| Size | 19.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
110029f0760f3852f8973d9dc6a9fa55db3333d92c07351dfa13adb8bb4ce02e
|
|
BLAKE2b-256 checksum How to use checksums |
7682c7d45e68759b9e3635cd33c51e3b74074d1399cf7c29be4844b7a129a3d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.
Transparency logRelease files / piv_smartcard-0.1.0-py3-none-any.whl
| Download URL | piv_smartcard-0.1.0-py3-none-any.whl |
|---|---|
| Size | 20.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
129d27139bce924355936ab229176eaab38bdf7e965d1505ee5fff6a34416e0c
|
|
BLAKE2b-256 checksum How to use checksums |
e15535aaee93eb9ba19c33b6574f9313a5318376d065971f95a7f57d2872acd5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.
Transparency log