dotnet immagine mancante

In questo articolo scoprirai come leggere i dati della CIE – Carta d’identità elettronica da un punto di vista tecnico, utilizzando un lettore NFC compatibile e un’app sviluppata in .NET. Analizzeremo i protocolli utilizzati, i formati dei dati e un esempio pratico di implementazione.

Immagine Nfc Cie mancante

Cos’è la CIE?

Dal punto di vista informatico, la CIE è una smart card contactless conforme allo standard ICAO 9303, lo stesso impiegato nei passaporti elettronici. I dati vengono salvati principalmente in due modalità:

  • Nel chip NFC, suddivisi in Data Group (DG). Alcuni dei più rilevanti sono:
    • DG1: dati anagrafici e MRZ
    • DG2: fotografia
    • DG11: dati personali come l’indirizzo
    • DG3 / DG4: impronte digitali (ad accesso riservato)
  • Nella MRZ (Machine Readable Zone), stampata sul retro della carta.

MRZ e protocolli di accesso

La MRZ è composta da tre righe OCR-B da 30 caratteri ciascuna. Questo blocco di testo serve come base per l’autenticazione tramite i protocolli:

  • BAC (Basic Access Control)
  • PACE (Password Authenticated Connection Establishment), più sicuro e moderno

Il protocollo PACE utilizza il codice CAN stampato sulla carta per accedere in sicurezza ai DG1, DG2 e DG11.

Lettura della CIE con un lettore NFC

immagine acr1252u mancante
ACR1252U

Per leggere la CIE, è necessario un lettore NFC compatibile con le specifiche seguenti:

  • Supporto ISO/IEC 14443 Tipo A e B (minimo 14443-4)
  • Capacità di inviare/ricevere comandi APDU
  • Compatibilità con PC/SC
  • Supporto per i protocolli PACE, BAC, EAC

Nel mio caso ho utilizzato un ACR1252U, un lettore economico ma adatto allo scopo.

L’applicazione in .NET

Per imparare .NET, ho realizzato una piccola app desktop che legge i dati della CIE e li invia via WebSocket a un’applicazione client, ad esempio una WebApp.

L’idea nasce dall’esigenza di compilare automaticamente i dati anagrafici in un gestionale, evitando l’inserimento manuale.

Funzionamento dell’app:

  • Si avvia in background (non ha GUI)
  • Si collega al lettore NFC
  • Apre un server WebSocket su localhost:8080
  • Trasmette i dati letti dalla CIE in formato JSON al client connesso

Codice: avvio dell’app e connessione WebSocket

L’app non prevede una GUI quindi si avvia in background

static void Main() {

    SetAppUserModelId("Cie Reader");

    Application.SetHighDpiMode(HighDpiMode.SystemAware);

    Application.EnableVisualStyles();

    Application.SetCompatibleTextRenderingDefault(false);

    Application.Run(new TrayAppContext());           

}

Una volta avviata, crea una WebSocket e si connette al lettore NFC

webSocketServer = new WebSocketServer();          

reader = new Reader();

Gestione lettura e parsing dei dati

Le letture possono fallire a causa dell’hardware NFC. Per questo motivo è presente un sistema di retry. Quando la lettura ha successo, si istanzia la classe:

C_CIE readDocument = new C_CIE(a);

I dati sono serializzati nel formato TLV (Tag-Length-Value). Ecco alcuni tag usati per deserializzare:

public static readonly byte[] KEY_FULL_NAME = new byte[]{ 0x5F, 0x0E };

public static readonly byte[] KEY_BIRTH_ADDRESS = new byte[] { 0x5F, 0x11 };

public static readonly byte[] KEY_ADDRESS = new byte[] { 0x5F, 0x42 };

public static readonly byte[] KEY_CF = new byte[] { 0x5F, 0x10 };

public static readonly byte[] KEY_MRZ = new byte[] { 0x5F, 0x1F };

public static readonly byte[] KEY_DATE_ISSUE = new byte[] { 0x5F, 0x26 };

public static readonly byte[] KEY_DATE_EXPIRE = new byte[] { 0x5F, 0x24 };

public static readonly byte[] KEY_BIRTH_DATE = new byte[] { 0x5F, 0x57 };

Se alcuni dati non sono disponibili, è possibile recuperarli dalla MRZ, come ad esempio la data di nascita:

string[] lines = mrz.Split('\n');

string rawDate = lines[0].Substring(30, 6);

string yearPrefix = rawDate.Substring(0, 2).CompareTo("50") >= 0 ? "19" : "20";

birthDate = yearPrefix + rawDate.Substring(0, 2) + "-" + rawDate.Substring(2, 2) + "-" + rawDate.Substring(4, 2);

o la data di scadenza del documento

string[] lines = mrz.Split('\n');

string expiryRaw = lines[0].Substring(38, 6); // YYMMDD

string yearPrefix = expiryRaw.Substring(0, 2).CompareTo("50") >= 0 ? "19" : "20";

dateExpire = expiryRaw.Substring(4,2) + "/" + expiryRaw.Substring(2, 2) + "/" + yearPrefix + expiryRaw.Substring(0,2);

Invio dei dati via WebSocket

L’app invia i dati letti dalla CIE a tutti i client connessi:

public async Task BroadcastMessageAsync(string message)

{

    byte[] buffer = Encoding.UTF8.GetBytes(message);

    var tasks = _connectedSockets.Values

        .Where(s => s.State == WebSocketState.Open)

        .Select(s => s.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None));

    await Task.WhenAll(tasks);

}

L’elenco delle connessioni attive è gestito da:

private readonly ConcurrentDictionary<Guid, WebSocket> _connectedSockets = new();

SDK utilizzato per la lettura CIE

La logica di decrypt e lettura dati è stata realizzata grazie allo SDK open source messo a disposizione da IPA – Istituto Poligrafico e Zecca dello Stato, disponibile su GitHub.

Limiti attuali dell’applicazione

  1. Funziona solo con CIE v2.x
  2. Nessuna autenticazione sul canale WebSocket
  3. Configurazione hardcoded (localhost:8080)
  4. Nessuna interfaccia utente

Tutti questi aspetti verranno affrontati in una versione futura.

Conclusione

Sviluppare questa applicazione mi ha permesso di scoprire il mondo dello sviluppo desktop in .NET, che fino ad ora mi era completamente sconosciuto.

Il progetto ha ampi margini di miglioramento, sia sul piano tecnico che funzionale.


Chiunque voglia contribuire o suggerire migliorie è il benvenuto sul mio GitHub!

Di admin

1 commento su “Come leggere la CIE tramite NFC in .NET”

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *