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:
- 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
- .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
- The .NET PKCS#11 transforms the hash into an ASCII string.
- 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.