The pcsc-sharp library is wrapper that provides access to the Personal Computer/Smart Card Resource Manager using the system's native PC/SC API. It implements partial ISO7816 support and is written to run on both Windows and Unix (.Net Core or Mono using PCSC Lite).
pcsc-sharp is not a fully featured library for accessing vendor specific protocols. You must implement those protocols / applications yourself. For example: You can use pcsc-sharp to access NXP's Mirfare RFID chips, but pcsc-sharp does not provide any APDUs to request KEYs, authorize, etc.
pcsc-sharp does not contain any device drivers. A PC/SC compliant reader + driver is mandatory.
The GitHub issue tracker is not a support forum. Please contact your vendor for reader or card specific questions.
You can find PC/SC specific documentation here:
- Windows: Smart Card Resource Manager API
- Linux: PCSC lite project
-
Windows (winscard.dll)
- Windows 11 64-bit
- Windows 10 64-bit Professional
- Windows 10 32-bit Professional
-
Linux (PC/SC lite)
- Ubuntu Linux 64-bit
- Ubuntu Linux 32-bit
-
MacOS X
-
Raspberry Pi / Linux ARM
- linux-arm
Each operation requires a valid context. See SCardEstablishContext for more information.
var contextFactory = ContextFactory.Instance; using (var context = contextFactory.Establish(SCardScope.System)) { // your code }
Basic rules / best practices:
- One context per smartcard / reader.
- One context per
SCardMonitor. - The context must be disposed of after usage to free system resources.
- The context must not be disposed of if your application still accesses the smartcard / reader.
See SCardListReaders.
var contextFactory = ContextFactory.Instance; using (var context = contextFactory.Establish(SCardScope.System)) { Console.WriteLine("Currently connected readers: "); var readerNames = context.GetReaders(); foreach (var readerName in readerNames) { Console.WriteLine("\t" + readerName); } }
var contextFactory = ContextFactory.Instance; using (var ctx = contextFactory.Establish(SCardScope.System)) { using (var isoReader = new IsoReader(ctx, "ACME Smartcard reader", SCardShareMode.Shared, SCardProtocol.Any, false)) { var apdu = new CommandApdu(IsoCase.Case2Short, isoReader.ActiveProtocol) { CLA = 0x00, // Class Instruction = InstructionCode.GetChallenge, P1 = 0x00, // Parameter 1 P2 = 0x00, // Parameter 2 Le = 0x08 // Expected length of the returned data }; var response = isoReader.Transmit(apdu); Console.WriteLine("SW1 SW2 = {0:X2} {1:X2}", response.SW1, response.SW2); // .. } }
using (var ctx = ContextFactory.Instance.Establish(SCardScope.System)) { using (var reader = ctx.ConnectReader("OMNIKEY CardMan 5x21 0", SCardShareMode.Shared, SCardProtocol.Any)) { var cardAtr = reader.GetAttrib(SCardAttribute.AtrString); Console.WriteLine("ATR: {0}", BitConverter.ToString(cardAtr)); Console.ReadKey(); } }
var monitorFactory = MonitorFactory.Instance; var monitor = monitorFactory.Create(SCardScope.System); // connect events here.. monitor.StatusChanged += (sender, args) => Console.WriteLine($"New state: {args.NewState}"); monitor.Start("OMNIKEY CardMan 5x21-CL 0"); Console.ReadKey(); // Press any key to exit monitor.Cancel(); monitor.Dispose();
Checkout the Examples directory.
Build tools
- .Net 8.0 SDKs (Multi target build)
Compile with
dotnet build -c Release
Compile with
dotnet publish -r linux-arm