Problema con la lettura di varie Smart Card

di il
3 risposte

Problema con la lettura di varie Smart Card

Buongiorno a tutti!
Mi chiamo Simone e mi piace utilizzare il buon vecchio Visual Basic 6 per risolvere molti dei problemi che incontro qui a lavoro.

Sto realizzando un semplicissimo lettore di Smart Card, affinchè semplicemente registri gli accessi e le uscite di un centinaio di persone. In rete ho trovato molte soluzioni, ma fin troppo complicate! Ho bisogno che faccia una semplice registrazione, senza calcoli stipendiali, turnazioni, etc ...

Per cui ho navigato fino a trovare un esempio di Ugo Chirico per connettermi al lettore ed alla Smart Card (tipo Tessera Sanitaria per intenderci).

Gli unici dati che mi servono sono:
- Cognome;
- Nome;
- Codice Fiscale.

Se lo testo su una singola Smart Card funziona, ma se provo a inserirne un'altra, legge una stringa assolutamente casuale e naturalmente va in errore poichè non riesce a "lavorarla" come vorrei.
La mia impressione è che in qualche modo che la connessione alla carta precedente "sporchi" le connessioni successive.

Allego il codice su cui sto impazzendo, sia per farmi aiutare da qualche anima pia, sia per condividere ciò che ho faticosamente trovato e messo insieme per creare una cosa che sembrava banale ed invece ....

Grazie in anticipo per l'attenzione e vi auguro una buona giornata.

Simone

    Dim hContext As Long
    Dim hCard As Long
    Dim retval As Long
    Dim readers As String * 256
    Dim groups As String * 256
    Dim activeprotocol As Long
    Dim readerlen As Long
    
    retval = SCardEstablishContext(SCARD_SCOPE_USER, 0, 0, hContext)
    If (retval <> 0) Then MsgBox ("Errore: " & CStr(retval))
    
    readerlen = 256
    
    ' FACCIO UNA LISTA DEI LETTORI DISPONIBILI
    retval = SCardListReaders(hContext, groups, readers, readerlen)
    If (retval <> 0) Then MsgBox ("Lettore non trovato!")
    
    ' ######################################################################
    ' APRO LA CONNESSIONE CON LA CARTA
    retval = SCardConnect(hContext, GetReader(readers, 1), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0_OR_T1, hCard, activeprotocol)
    
    If (retval <> 0) Then
        MsgBox ("Tessera non inserita. Errore: " & CStr(retval))
        Exit Sub
    End If
    ' ######################################################################
    
        
    Dim apdu(261) As Byte
    Dim recvbuf(258) As Byte
    Dim recvlen As Integer
    Dim iosendreq As SCARD_IO_REQUEST
    Dim iorecvreq As SCARD_IO_REQUEST
    
    ' STRINGA APDU
    apdu(0) = &H0   'CLA
    apdu(1) = &HCA  'INS
    apdu(2) = &H0   'P1
    apdu(3) = &H81  'P2
    apdu(4) = &H0   'LC
    apdu(5) = &H0   'LE
    
    recvlen = 257
    
    iosendreq.dwprotocol = activeprotocol
    iosendreq.dbPciLength = Len(iosendreq)
    iorecvreq.dwprotocol = activeprotocol
    iorecvreq.dbPciLength = Len(iosendreq)
    
    retval = SCardTransmit(hCard, iosendreq, apdu(0), 6, iorecvreq, recvbuf(0), recvlen)
    If (retval <> 0) Then MsgBox ("Errore nella trasmissione: " & CStr(retval))
    
    '---------------------
    '      LIVELLO MF
    '---------------------
    apdu(0) = &H0   'CLA
    apdu(1) = &HA4 'INS
    apdu(2) = &H9  'P1
    apdu(3) = &H0  'P2
    apdu(4) = &H2  'LC
    apdu(5) = &H3F
    apdu(6) = &H0
    
    recvlen = 257
    
    iosendreq.dwprotocol = activeprotocol
    iosendreq.dbPciLength = Len(iosendreq)
    iorecvreq.dwprotocol = activeprotocol
    iorecvreq.dbPciLength = Len(iosendreq)
    
    retval = SCardTransmit(hCard, iosendreq, apdu(0), 7, iorecvreq, recvbuf(0), recvlen)
    If (retval <> 0) Then
            MsgBox ("Errore n." & CStr(retval))
    End If
    
    '---------------------
    '      LIVELLO EF 1100
    '---------------------
    
    apdu(0) = &H0   'CLA
    apdu(1) = &HA4 'INS
    apdu(2) = &H9  'P1
    apdu(3) = &H0  'P2
    apdu(4) = &H2  'LC
    apdu(5) = &H11
    apdu(6) = &H0
    
    recvlen = 257
    
    iosendreq.dwprotocol = activeprotocol
    iosendreq.dbPciLength = Len(iosendreq)
    iorecvreq.dwprotocol = activeprotocol
    iorecvreq.dbPciLength = Len(iosendreq)
    
    retval = SCardTransmit(hCard, iosendreq, apdu(0), 7, iorecvreq, recvbuf(0), recvlen)
    If (retval <> 0) Then
            MsgBox ("Errore n." & CStr(retval))
    End If
    
    '---------------------
    '      LIVELLO EF 1102 - DATI PERSONALI CONTENUTI NELLA CARTA
    '---------------------
    
    apdu(0) = &H0   'CLA
    apdu(1) = &HA4 'INS
    apdu(2) = &H9  'P1
    apdu(3) = &H0  'P2
    apdu(4) = &H2  'LC
    apdu(5) = &H11
    apdu(6) = &H2
    
    recvlen = 257
    
    iosendreq.dwprotocol = activeprotocol
    iosendreq.dbPciLength = Len(iosendreq)
    iorecvreq.dwprotocol = activeprotocol
    iorecvreq.dbPciLength = Len(iosendreq)
    
    retval = SCardTransmit(hCard, iosendreq, apdu(0), 7, iorecvreq, recvbuf(0), recvlen)
    If (retval <> 0) Then
            MsgBox ("Errore n." & CStr(retval))
    End If
    
    
    ' LEGGO I BINARY PROVENIENTI DALLA CARTA
    apdu(0) = &H0   'CLA
    apdu(1) = &HB0 'INS
    apdu(2) = &H0  'P1
    apdu(3) = &H0  'P2
    apdu(4) = &H96  'LC
    
    recvlen = 257
    
    iosendreq.dwprotocol = activeprotocol
    iosendreq.dbPciLength = Len(iosendreq)
    iorecvreq.dwprotocol = activeprotocol
    iorecvreq.dbPciLength = Len(iosendreq)
    
    retval = SCardTransmit(hCard, iosendreq, apdu(0), 5, iorecvreq, recvbuf(0), recvlen)
    If (retval <> 0) Then
            MsgBox ("Errore n." & CStr(retval))
    End If
    
    risposta = ""
    
    For K = 0 To apdu(4) - 1: risposta = risposta + Chr(recvbuf(K)): Next K
        
    ' ESTRAGGO COGNOME, NOME, CODICE FISCALE
    ' IN BASE ALLA POSIZIONE NELLA STRINGA DI RISPOSTA DALLA CARTA
    
    Dim PosIni
    PosIni = 1
    
    risposta = Trim(risposta)
    risposta = Mid(risposta, 7)
    LenEmettitore = HexToLong(Int(Mid(risposta, PosIni, 2)))
    PosIni = PosIni + 2
    Emettitore = Mid(risposta, PosIni, LenEmettitore)
    
    PosIni = PosIni + LenEmettitore
    LenRilascio = Int(Mid(risposta, PosIni, 2))
    PosIni = PosIni + 2
    Rilascio = Mid(risposta, PosIni, LenRilascio)
    
    PosIni = PosIni + LenRilascio
    LenScadenza = Int(Mid(risposta, PosIni, 2))
    PosIni = PosIni + 2
    Scadenza = Mid(risposta, PosIni, LenScadenza)
    
    PosIni = PosIni + LenScadenza
    LenCognome = Int(Mid(risposta, PosIni, 2))
    PosIni = PosIni + 2
    Cognome = Mid(risposta, PosIni, LenCognome)
    txtDati.Text = Cognome
    
    PosIni = PosIni + LenCognome
    LenNome = Int(Mid(risposta, PosIni, 2))
    PosIni = PosIni + 2
    Nome = Mid(risposta, PosIni, LenNome)
    txtDati.Text = txtDati.Text & " - " & Nome
    
    PosIni = PosIni + LenNome
    LenValore1 = Int(Mid(risposta, PosIni, 2))
    PosIni = PosIni + 2
    PosIni = PosIni + LenValore1
    LenValore2 = Int(Mid(risposta, PosIni, 2))
    PosIni = PosIni + 2
    PosIni = PosIni + LenValore2
    LenValore3 = Int(Mid(risposta, PosIni, 2))
    PosIni = PosIni + 2
    PosIni = PosIni + LenValore3
    
    LenCodice = HexToLong(Int(Mid(risposta, PosIni, 2)))
    PosIni = PosIni + 2
    Codice = Mid(risposta, PosIni, LenCodice)
    txtDati.Text = txtDati.Text & " - " & Codice
    
    ' ############################################################################
    ' CHIUDO LA CONNESSIONE CON LA CARTA
   
    retval = SCardDisconnect(hCard, SCARD_LEAVE_CARD)
    If (retval <> 0) Then MsgBox ("Errore: " & CStr(retval))
    
    retval = SCardReleaseContext(hContext)
    If (retval <> 0) Then MsgBox ("Errore: " & CStr(retval))

    
    ' ############################################################################

3 Risposte

  • Re: Problema con la lettura di varie Smart Card

    Credo proprio di aver risolto!

    L'errore è nelle istruzioni APDU che passavo alla carta.

    Praticamente, le Smart Card hano una sorta di FileSystem che può essere "navigato" solo inviando dei comandi in esadecimale.
    Per raggiungere il file che contiene i dati personali bisogna inserire i seguenti comandi in APDU:
    00 A4 00 00 02 3F 00 - come se scrivessi CD ... per aprire la cartella principale (MF)
    00 A4 00 00 02 11 00 - entro nella cartella successiva (DF1)
    00 A4 00 00 02 11 02 - entro nella cartella che contiene i file di dati personali (EF1)
    00 B0 00 00 96 - leggo i binary di quanto contenuto

    Considerate che il binary che ottenete è una cose del genere:
    0000990461200829042013082704201906PRATICO06SIMONE082707197701M0010abcabc57....

    Sembra una cosa assurda, ma è una stringhe che risponde a precise regole che sono riuscito a capire grazie a questa pagina http://www.mmxforge.net/index.php/sviluppo/python/item/9-lettura-dei-dati-della-tessera-sanitaria-con-python

    OK. Posso continuare con il progetto. Spero che quanto da me scoperto possa essere utile a qualcun altro e velocizzare i tempi!

    Buona giornata!
  • Re: Problema con la lettura di varie Smart Card

    Niente da fare...

    Continuo ad avere problemi tra una SmartCard e l'altra. Ogni tanto mi legge una e legge male l'altra o viceversa ...

    Sto girando per internet, ma le informazioni a riguardo sono poche e caotiche!

    Mah!
  • Re: Problema con la lettura di varie Smart Card

    Io sono interessato all'approccio che hai utilizzato.
    Io ci sono riuscito in parte usando un activex trovata sul web
    Sono riuscito a leggere tessere sanitarie, carte d'identita e alcune carte di diverso tipo ma compatibili cns
    Ho ancora problemi, pero' con alcune carte che hanno specifiche leggermente diverse
    MI piacerebbe scambiare qualche spunto
Devi accedere o registrarti per scrivere nel forum
3 risposte