Question

I have smart card and reader (Gemalto). I want to read serial number of card using C#. I read documents / libraries on Gemalto Support Site but there are no information useful for me.

I hope someone have exp about Gemalto help me some examples !

Thanks so much !

Was it helpful?

Solution 3

If you mean serialnumber on the card you can do following:

You need to make reference the to the Off card dll in Gemalto SDK. SmartCard.Runtime.dll SmartCard_Stub.dll

SmartCard.Transport.PCSC.SelectDialog dialog = new SmartCard.Transport.PCSC.SelectDialog();
CardAccessor ca = new CardAccessor(dialog.SelectedReader);
if(ca.Logon())
{
ca.GetSerialNumber();
}

If you mean serial number on a certificate its a total different approach.

OTHER TIPS

You have to send APDU to smart card asking for card product life cycle data i.e (CPLC data).
Some specific types of cards have Card Production Life Cycle (CPLC) data. For example, JCOP cards have this at GET DATA or GETCPLCDATA at 0x9F7F tag or 0x0101 tag. I believe This is a Global Platform specific tag. Find what specification your card support. For Gemalto card, I hope it will work. Data what i got from my gemalto card by querying CPLC data is:

For 0x9F7F:

IC Fabricator :2 Bytes
IC Type : 2 Bytes
Operating System ID : 2 Bytes
Operating System release date : 2 Bytes
Operating System release level : 2 Bytes
IC Fabrication Date : 2 Bytes (Y DDD) date in that year
IC Serial Number : 4 Bytes
IC Batch Identifier : 2 Bytes
IC Module Fabricator : 2 Bytes
IC Module Packaging Date :  2 Bytes
ICC Manufacturer : 2 Bytes
IC Embedding Date :2 Bytes
IC Pre-Personalizer : 2 Bytes
IC Pre-Perso. Equipment Date : 2 Bytes
IC Pre-Perso. Equipment ID : 4 Bytes
IC Personalizer : 4 Bytes
IC Personalization Date : 2 Bytes
IC Perso. Equipment ID : 4 Bytes

For 0x0101:

Card serial number: 8 bytes  
Reserved bytes: 3 bytes 0
Flow identification: 1 byte  
Reserved bytes: 4 bytes 

Sorry i cant provide exact bytes and it might vary in your case. just check for what tag your card support. and Better refer to Global Platform documentation and ISO 7816 standard (http://www.ttfn.net/techno/smartcards/iso7816_4.html). I hope This is what you are looking for.

Here's how to get it via PowerShell:

Note: this is specifically for Gemalto IDPrime .NET cards which are being replaced by the IDPrime MD product line. See the end of this post for more info.

Using Gemalto IDPrime .NET SDK

Add-Type -Path "C:\Program Files (x86)\Gemalto\NET Smartcard Framework SDK\v2.2.180\Libraries\On Card\Framework Libraries\v2.1.213.9175\SmartCard.dll"
Add-Type -Path "C:\Program Files (x86)\Gemalto\NET Smartcard Framework SDK\v2.2.180\bin\SmartCard_stub.dll"
Add-Type -Path "C:\Program Files (x86)\Gemalto\NET Smartcard Framework SDK\v2.2.180\bin\SmartCard.Runtime.dll"
$Reader = New-Object SmartCard.Transport.PCSC.SelectDialog
$Reader.ShowDialog() | Out-Null

$SmartCard = New-Object SmartCard.Accessor.CardAccessor($Reader.SelectedReader)

$SmartCardSN = [System.BitConverter]::ToString($SmartCard.GetSerialNumber())

Write-Host "Smartcard Serial Number: $SmartCardSN"

$SmartCard.Dispose()
$Reader.Dispose()

Using Gemalto IDPrime .NET PKCS #11 Drivers

If you want to use the PKCS11 library, it can be done as follows. However, this route comes with a WARNING since it returns a hash of the serial number and NOT the actual serial number. Per Gemalto Documentation:

The .NET PKCS#11 library performs an MD5 hash of the CSN provided by the minidriver giving a result of 16-bytes. As the C_GetTokenInfo string is only 16 bytes it can display 16 characters of the hash result only in ASCII format. These 16 characters are the 8 MSB (leftmost bytes) of the hash result.

Example:

  1. The .NET PKCS#11 library requests the 12-byte Card Serial Number (CSN) from the card ID file: 0x57 0x01 0x13 0x51 0x26 0xC7 0xD6 0x10 0x29 0x27 0xFF 0xFF
  2. .NET PKCS#11 performs an MD5 hash on the CSN giving a 16-byte result: 0x05 0xCB 0x00 0x3D 0x76 0xD3 0xE9 0x4F 0x74 0x13 0xD8 0x74 0x38 0x8C 0xBF 0xB4
  3. The .NET PKCS#11 transforms the hash into an ASCII string.
  4. Finally it fills the serialNumber field of the TokenInfo structure (on 16 bytes) with the first 16 characters of the ASCII string: “05CB003D76D3E94F” corresponding to the 8 MSB of the hash.
# www.pkcs11interop.net
Add-Type -Path "C:\SomeFolder\Pkcs11Interop.4.0.0\lib\net45\Pkcs11Interop.dll"

# Load Gemalto driver
# 1 = AppType.SingleThreaded
$pkcs11 = New-Object Net.Pkcs11Interop.HighLevelAPI.Pkcs11("C:\Program Files (x86)\Gemalto\DotNet PKCS11\gtop11dotnet64.dll",1)

# 0 = SlotsType.WithTokenPresent
$Slots = $pkcs11.GetSlotList(0)

$CardReader = $Slots[0] # Usually first slot

$CardReader.GetTokenInfo().SerialNumber

$CardReader.CloseAllSessions()
$pkcs11.Dispose()

Gemalto Card Types

The above examples are based off Gemalto IDPrime .NET cards which are being retired. The End of Sale (EOS) announcement is here.

IDPrime .Net
IDPrime .Net Bio

Key Dates: 
Milestone                  Date
Last-Time-Buy (LTB)        September 29, 2017
End-of-Sale (EOS)          September 30, 2017
End-of-Life (EOL)          September 30, 2018

Replacement

Per the EOS announcement PDF:

Products Gemalto’s family of IDPrime .NET 510/511 smart cards will be replaced by the IDPrime MD 83x and IDPrime MD 84x series of smart cards.

Programming the Replacement cards

I've included the information about distinguishing card types because I have a Gemalto IDPrime MD 830 for testing and the above techniques do not work. In fact, the card doesn't even show as being present in the reader using the above techniques.

See this post. Things might differ slightly on your card (CLA byte in particular).

Basically you need to select the root of the card file system (MF, a.k.a. 3F00), then select the card's EFiccid (2FE2) and read the contents. Pretty simple in theory.

For each step there is a dedicated APDU command. If the Gemalto library allows you to send APDUs, you should be good to go.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top