/// <summary> /// Will try to connect to _connectedReader and read the card. /// </summary> /// <returns>Either the data from the card or the error message. Or if 'uidOnly' is true, just the UID prefixed with 'UID^' and ending with '^'</returns> public string ReadCard(bool uidOnly = false) { SCardContext context = new SCardContext(); context.Establish(SCardScope.System); SCardReader reader = new SCardReader(context); SCardError result = reader.Connect(_connectedReader, SCardShareMode.Shared, SCardProtocol.Any); if (result != SCardError.Success) { context.Dispose(); reader.Dispose(); return string.Format("No card is detected (or reader reserved by another application){0}{1}", Environment.NewLine, SCardHelper.StringifyError(result)); } string[] readerNames; SCardProtocol protocol; SCardState state; byte[] atr; result = reader.Status(out readerNames, out state, out protocol, out atr); if (result != SCardError.Success) { context.Dispose(); reader.Dispose(); return string.Format("Unable to read from card.{0}{1}", Environment.NewLine, SCardHelper.StringifyError(result)); } string message = string.Format("Card detected:{0}Protocol: {1}{0}State: {2}{0}ATR: {3}{0}", Environment.NewLine, protocol, state, BitConverter.ToString(atr ?? new byte[0])); CommandApdu apdu = new CommandApdu(IsoCase.Case2Short, reader.ActiveProtocol) { CLA = 0xFF, Instruction = InstructionCode.GetData, P1 = 0x00, P2 = 0x00, Le = 0 }; result = reader.BeginTransaction(); if (result != SCardError.Success) { context.Dispose(); reader.Dispose(); return string.Format("Cannot start transaction.{0} {1}", Environment.NewLine, SCardHelper.StringifyError(result)); } SCardPCI recievePci = new SCardPCI(); IntPtr sendPci = SCardPCI.GetPci(reader.ActiveProtocol); byte[] recieveBuffer = new byte[256]; result = reader.Transmit(sendPci, apdu.ToArray(), recievePci, ref recieveBuffer); if (result != SCardError.Success) { context.Dispose(); reader.Dispose(); return string.Format("Cannot transmit data.{0} {1}", Environment.NewLine, SCardHelper.StringifyError(result)); } var responseApdu = new ResponseApdu(recieveBuffer, IsoCase.Case2Short, reader.ActiveProtocol); message += string.Format("SW1: {1}{0}SW2: {2}{0}", Environment.NewLine, responseApdu.SW1, responseApdu.SW2); string data = responseApdu.HasData ? BitConverter.ToString(responseApdu.GetData()) : "--"; if (uidOnly) { context.Dispose(); reader.Dispose(); return string.Format("UID^{0}^", data); } message += string.Format("UID: {0}",data); reader.EndTransaction(SCardReaderDisposition.Leave); reader.Disconnect(SCardReaderDisposition.Reset); context.Dispose(); reader.Dispose(); return message; }
public static void Main() { using (var context = new SCardContext()) { context.Establish(SCardScope.System); var readerNames = context.GetReaders(); if (readerNames == null || readerNames.Length < 1) { Console.WriteLine("You need at least one reader in order to run this example."); Console.ReadKey(); return; } var readerName = ChooseRfidReader(readerNames); if (readerName == null) { return; } using (var rfidReader = new SCardReader(context)) { var sc = rfidReader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any); if (sc != SCardError.Success) { Console.WriteLine("Could not connect to reader {0}:\n{1}", readerName, SCardHelper.StringifyError(sc)); Console.ReadKey(); return; } var apdu = new CommandApdu(IsoCase.Case2Short, rfidReader.ActiveProtocol) { CLA = 0xFF, Instruction = InstructionCode.GetData, P1 = 0x00, P2 = 0x00, Le = 0 // We don't know the ID tag size }; sc = rfidReader.BeginTransaction(); if (sc != SCardError.Success) { Console.WriteLine("Could not begin transaction."); Console.ReadKey(); return; } Console.WriteLine("Retrieving the UID .... "); var receivePci = new SCardPCI(); // IO returned protocol control information. var sendPci = SCardPCI.GetPci(rfidReader.ActiveProtocol); var receiveBuffer = new byte[256]; var command = apdu.ToArray(); sc = rfidReader.Transmit( sendPci, // Protocol Control Information (T0, T1 or Raw) command, // command APDU receivePci, // returning Protocol Control Information ref receiveBuffer); // data buffer if (sc != SCardError.Success) { Console.WriteLine("Error: " + SCardHelper.StringifyError(sc)); } var responseApdu = new ResponseApdu(receiveBuffer, IsoCase.Case2Short, rfidReader.ActiveProtocol); Console.Write("SW1: {0:X2}, SW2: {1:X2}\nUid: {2}", responseApdu.SW1, responseApdu.SW2, responseApdu.HasData ? BitConverter.ToString(responseApdu.GetData()) : "No uid received"); rfidReader.EndTransaction(SCardReaderDisposition.Leave); rfidReader.Disconnect(SCardReaderDisposition.Reset); Console.ReadKey(); } } }
private byte[] ReadFileNextBlock(int offSet, int lenght) { TS.TraceV("Start ReadFileNextBlock, offset = \"{0}\", length = \"{1}\".", offSet, lenght); byte[] pbRecvBuffer = new byte[lenght + 2]; //// Last 2 bytes are sw1 + sw2 byte[] offSetArr = MTVReader.Converter.IntToByteArray(offSet, 2); byte[] lenghtArr = MTVReader.Converter.IntToByteArray(lenght, 1); byte[] readFile = new byte[] { 0x00, 0xB0, offSetArr[0], offSetArr[1], lenghtArr[0] }; SCardError err = this.crdReader.Transmit(readFile, ref pbRecvBuffer); if (err != SCardError.Success) { TS.TraceV("CardReaderException: \"{0}\".", SCardHelper.StringifyError(err)); throw new CardReaderException(err, "Unfortunately, this smart card can not be read"); } ResponseApdu resp = new ResponseApdu(pbRecvBuffer, IsoCase.Case4Extended, this.crdReader.ActiveProtocol); if ((resp.SW1 != 0x90) && (resp.SW2 != 0x00)) { throw new CardReaderException(string.Format("Error reading next block for file at offset {0}, length {1}", offSet, lenght)); } TS.TraceV("End ReadFileNextBlock."); return resp.GetData(); }
public byte[] ReadFile(byte[] AID, byte[] FileID) { TS.TraceI("Readfile with AID \"{0}\" and FileID \"{1}\".", Helper.ByteArrayToString(AID), Helper.ByteArrayToString(FileID)); SelectApplet(AID); if (FileID.Length != 0x02) { throw new ArgumentException("Invalid length FileID", "FileID"); } if (this.crdReader == null) { throw new CardReaderException("No valid reader available"); } byte[] pbRecvBuffer = new byte[256]; //// Send SELECT File byte[] selectFile = new byte[] { 0x00, 0xA4, 0x02, 0x04, 0x02, FileID[0], FileID[1], 0x00 }; TS.TraceV("Select file with command: \"{0}\".", Helper.ByteArrayToString(selectFile)); /* 00 = Class A4 = Instructie 02 = P1 (select EF under current DF) 04 = P2 (return FCP data) 02 = Lc XX = Data XX = Data 00 = Le */ SCardError err = this.crdReader.Transmit(selectFile, ref pbRecvBuffer); if (err != SCardError.Success) { throw new CardReaderException(err, SCardHelper.StringifyError(err)); } ResponseApdu resp = new ResponseApdu(pbRecvBuffer, IsoCase.Case4Extended, this.crdReader.ActiveProtocol); if ((resp.SW1 != 0x90) && (resp.SW2 != 0x00)) { return null; } byte[] fileInfo = resp.GetData(); if (fileInfo == null) { throw new CardReaderException(string.Format( "No data available reading FileID \"{0}\" with AID \"{1}\".", Helper.ByteArrayToString(FileID), Helper.ByteArrayToString(AID))); } TLVList myanswer = TLV.Parse(new MemoryStream(fileInfo)); TLV fileLengthTLV = myanswer.getTag("1,62|1,80"); if (fileLengthTLV == null) { throw new CardReaderException("Missing tag: 1,62|1,80"); } int fileLength = Helper.ByteArrayToInt(fileLengthTLV.Value); TS.TraceV("File length = \"{0}\".", fileLength); //// Read the remaining bytes for this file byte[] fileData = new byte[fileLength]; int bytesRead = 0; const int blockSize = 255; TS.TraceV("Start reading file with blocksize \"{0}\".", blockSize); while (bytesRead < fileLength) { int lngth = blockSize; if (fileLength - bytesRead < blockSize) { //// Cannot read an entire block anymore; adjust length of data to read lngth = fileLength - bytesRead; if (lngth == 0) { break; } } byte[] nextBlock = ReadFileNextBlock(bytesRead, lngth); Buffer.BlockCopy(nextBlock, 0, fileData, bytesRead, nextBlock.Length); bytesRead += nextBlock.Length; TS.TraceV("\"{0}\" bytes read.", bytesRead); } TS.TraceI("File read."); return fileData; }
public string ReadSmartCard() { using (var context = new SCardContext()) { context.Establish(SCardScope.System); string readerName = null; try { string[] readerNames = context.GetReaders(); readerName = readerNames[0]; } catch(Exception ex) { return "error"; } if (readerName == null) { return "error"; } using (var rfidReader = new SCardReader(context)) { var sc = rfidReader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any); if (sc != SCardError.Success) { return "error";//"Could not connect to reader {0}:\n{1}"; } var apdu = new CommandApdu(IsoCase.Case2Short, rfidReader.ActiveProtocol) { CLA = 0xFF, Instruction = InstructionCode.GetData, P1 = 0x00, P2 = 0x00, Le = 0 // We don't know the ID tag size }; sc = rfidReader.BeginTransaction(); if (sc != SCardError.Success) { return "none";// "Could not begin transaction."; } var receivePci = new SCardPCI(); // IO returned protocol control information. var sendPci = SCardPCI.GetPci(rfidReader.ActiveProtocol); var receiveBuffer = new byte[256]; var command = apdu.ToArray(); sc = rfidReader.Transmit( sendPci, // Protocol Control Information (T0, T1 or Raw) command, // command APDU receivePci, // returning Protocol Control Information ref receiveBuffer); // data buffer if (sc != SCardError.Success) { return "none";//SCardHelper.StringifyError(sc); } var responseApdu = new ResponseApdu(receiveBuffer, IsoCase.Case2Short, rfidReader.ActiveProtocol); rfidReader.EndTransaction(SCardReaderDisposition.Leave); rfidReader.Disconnect(SCardReaderDisposition.Reset); int id = responseApdu.HasData ? BitConverter.ToInt32(responseApdu.GetData(),0) : -1; //int id = responseApdu.HasData ? System.Text.Encoding.UTF8.GetString(responseApdu.GetData()) : "none"; if (id < 0) id = id * (-1); return id.ToString(); } } return "none"; }