Skip to main content

eid_belgium 0.1.0 copy "eid_belgium: ^0.1.0" to clipboard
eid_belgium: ^0.1.0 copied to clipboard

Reads the Belgian eID, Kids ID and residence cards: identity, address, photo and certificates, with PIN, signature and chip checks.

eid_belgium #

Video tour Live demo Pub Version Build Maintainer Licence Platforms Donate with PayPal

Reads the Belgian eID, the Kids ID and the residence cards (EU, EU+, A to N) through their contact chip: identity, address, photo and certificates. None of it needs the PIN.

Install #

dependencies:
  eid_belgium: ^0.1.0
  eid_ccid: ^0.1.0 # a USB card reader, in a Flutter application

Read a card #

import 'package:eid_belgium/eid_belgium.dart';
import 'package:eid_ccid/eid_ccid.dart';

final readers = await CcidTransport.listReaders();
final transport = await CcidTransport.connect(readers.first);

final eid = await BelgianEidReader(transport).read();
eid.identity.lastName;        // Dupont
eid.identity.birthDate;       // 1985-07-30
eid.address?.municipality;    // Bruxelles
eid.photo;                    // a JPEG

await transport.disconnect();

Read on insertion #

final watcher = BelgianEidWatcher(
  CcidTerminal.any(),        // every reader, those plugged in later included
  autoRead: true,            // read as soon as the card is in
  parts: BelgianEidPart.all, // address, photo, signatures, nationalNumber
  acceptExpired: false,      // turn down expired cards
  acceptedTypes: null,       // every document type
  pinPrompt: null,           // ask for the PIN before reading
  rememberPhotos: true,      // skip the photo of a card read again
  verifySignatures: true,    // check the national register's signatures
  verifyCard: true,          // have the chip prove it is genuine
  trustedRoots: null,        // the Belgian roots
  onProgress: null,          // 0 to 1, for a progress bar
  onApdu: null,              // every command and answer, never the PIN
)..start();

watcher.events.listen((event) {
  switch (event) {
    case BelgianCardRead read:
      show(read.eid);
    case BelgianCardReadFailed failed:
      showError(failed.error);
    case BelgianCardRemoved _:
      clear();
    case BelgianCardInserted _ || BelgianPinVerified _:
      break;
  }
});

Every option can be changed at any time. parts, acceptExpired, acceptedTypes, verifySignatures, verifyCard, trustedRoots and onProgress also exist on BelgianEidReader.read.

Read less #

final eid = await reader.read(parts: {BelgianEidPart.address});
eid.photo;                    // null
eid.identity.nationalNumber;  // null, and removed from the raw fields too

Without the national number, the signatures are checked but not returned: they would give it away.

Turn cards down #

Three checks are on by default: an expired card, a card whose signatures do not hold and a cloned chip are turned down. acceptedTypes adds a fourth:

await reader.read(acceptedTypes: {BelgianDocumentType.eid});

A card turned down throws a BelgianCardRejectedException whose reason is expired, documentType, signature or notGenuine.

  • verifySignatures checks the national register's signatures of the identity, address and photo, and its certificate against the Belgian roots the package holds (belgianRootCertificates).
  • verifyCard has the chip sign a random challenge with its own key, which a copy of the files cannot do. It needs verifySignatures. Cards older than applet 1.8 cannot prove it: eid.authenticity is then notSupported. Each proof spends one of the 5000 the chip allows before it wants the PIN once.

On the web, the signatures are checked by the browser's WebCrypto. BelgianSignatureVerifier makes the same checks away from the card, on a server for instance, from eid.toJson().

PIN #

final watcher = BelgianEidWatcher(
  terminal,
  // triesLeft is null the first time. Return null if the holder gives up.
  pinPrompt: (triesLeft) => showMyPinDialog(triesLeft),
)..start();

await reader.verifyPin('1234');   // PinException: e.triesLeft, e.isBlocked
await reader.pinTriesLeft();      // without spending a try
await reader.changePin('1234', '5678');

Three wrong PINs in a row block the card. A PIN that is not 4 to 12 digits never reaches the card.

Certificates #

final certificates = await reader.readCertificates();
certificates.authentication?.subject.commonName; // Alice Specimen (Authentication)
await certificates.verify(BelgianSignatureVerifier()); // {} when all chain up

Revocation is not checked.

Helpers #

identity.age;                       // null when the birth date is partial
identity.isAdult;                   // certainly 18 or older
identity.isExpired;
formatBelgianNationalNumber(number, masked: true); // 85.07.30-***.**
formatBelgianCardNumber(identity.cardNumber);      // 592-1234567-89
BelgianDocumentType.eid.label(BelgianLanguage.nl); // Identiteitskaart
identity.fullName;                                 // Alice Marie Specimen
address.lines;                     // [Rue de la Loi 16, 1000 Bruxelles]
formatBelgianDate(identity.validUntil, BelgianLanguage.de); // 13. März 2034
identity.sex.label(BelgianLanguage.fr);            // Féminin
belgianErrorMessage(failed.error, BelgianLanguage.fr); // Carte expirée le ...

belgianErrorMessage turns any error of a read into a sentence for the holder, in French, Dutch, German or English.

Text is as the card holds it, in the language of the issuing municipality.

Without a reader #

import 'package:eid_belgium/testing.dart';

final card = SimulatedBelgianCard(lastName: 'Peeters', pin: '4321');
final eid = await BelgianEidReader(card).read();
card.remove();
card.insert();

A made-up national register signs it, whose root is trusted for the simulator alone. tamperedLastName and cloned give cards the checks turn down.

Personal data #

The holder must consent to their card being read, and only those authorised may use the national register number: leave nationalNumber out of parts otherwise.

Sources #

The documents published with the Belgian middleware, Fedict/eid-mw: card content v5.4, ID and address file contents v5.0, Belpic V1.8 reference manual.

License #

Released under the MIT licence.

More from COMAPPS #

Electronic identity cards in Dart:

Package What it does
eid APDUs, ISO 7816-4 file reading and the values national cards share.
eid_ccid The transport for a USB or PC/SC card reader.

Every package COMAPPS publishes is listed at packages.comapps.be.

0
likes
0
points
603
downloads

Publisher

verified publishercomapps.be

Weekly Downloads

Reads the Belgian eID, Kids ID and residence cards: identity, address, photo and certificates, with PIN, signature and chip checks.

Homepage
Repository (GitHub)
View/report issues

Topics

#eid #belgium #smartcard #identity #belpic

Funding

Consider supporting this project:

www.paypal.com

License

unknown (license)

Dependencies

crypto, eid, pointycastle

More

Packages that depend on eid_belgium