public object Clone() { ResponseApdu tmp = new ResponseApdu(); tmp.response = response; tmp.length = length; return(tmp); }
/// <summary> /// Creates a clone. /// </summary> /// <returns>A clone of the current instance.</returns> public virtual object Clone() { var tmp = new ResponseApdu { _response = _response, _length = _length }; return(tmp); }
/// <summary> /// Creates a clone. /// </summary> /// <returns>A clone of the current instance.</returns> public virtual object Clone() { var tmp = new ResponseApdu { FullApdu = FullApdu, Length = Length }; return(tmp); }
private ResponseApdu RetransmitOnInsufficientBuffer(CommandApdu commandApdu, ResponseApdu responseApdu, out SCardPCI receivePci) { int receiveBufferLength; var resendCmdApdu = (CommandApdu)commandApdu.Clone(); if (responseApdu.SW2 == 0) { resendCmdApdu.Le = 0; // 256 receiveBufferLength = 256 + 2; // 2 bytes for status word } else { resendCmdApdu.Le = responseApdu.SW2; receiveBufferLength = responseApdu.SW2 + 2; // 2 bytes for status word } var receiveBuffer = new byte[receiveBufferLength]; receivePci = new SCardPCI(); try { var sendBuffer = resendCmdApdu.ToArray(); // Shall we wait until we re-send we APDU/TPDU? if (RetransmitWaitTime > 0) { Thread.Sleep(RetransmitWaitTime); } // send Command APDU again with new Le value return(SimpleTransmit( sendBuffer, sendBuffer.Length, resendCmdApdu.Case, resendCmdApdu.Protocol, receivePci, receiveBuffer, receiveBufferLength)); } catch (WinErrorInsufficientBufferException ex) { throw new InvalidApduException( $"Retransmission failed because of unsufficient buffer. Le={resendCmdApdu.Le}", ex); } catch (InvalidOperationException ex) { throw new InvalidApduException( $"Got SW1={responseApdu.SW1:X}. Retransmission failed because of an invalid APDU.", resendCmdApdu, ex); } }
private ResponseApdu _SimpleTransmit(byte[] cmdApdu, int cmdApduLength, IsoCase isoCase, SCardProtocol proto, SCardPCI recvPci, ref byte[] recvBuf, ref int recvBufLength) { SCardError sc = SCardError.UnknownError; bool cmdSent = false; do { // send Command APDU to the card sc = reader.Transmit( SCardPCI.GetPci(reader.ActiveProtocol), cmdApdu, cmdApduLength, recvPci, recvBuf, ref recvBufLength); // Do we need to resend the command APDU? if (sc == SCardError.InsufficientBuffer && recvBuf.Length < recvBufLength) { // The response buffer was too small. recvBuf = new byte[recvBufLength]; // Shall we wait until we re-send we APDU? if (_retransmitWaitTime > 0) { Thread.Sleep(_retransmitWaitTime); } } else { cmdSent = true; } } while (cmdSent == false); if (sc == SCardError.Success) { ResponseApdu respApdu = new ResponseApdu(recvBuf, recvBufLength, isoCase, proto); return(respApdu); } // An error occurred, throw exception.. ThrowExceptionOnSCardError(sc); return(null); }
public object Clone() { ResponseApdu tmp = new ResponseApdu(); tmp.response = response; tmp.length = length; return tmp; }
private ResponseApdu IssueGetResponseCommand(CommandApdu commandApdu, ResponseApdu lastResponseApdu, Response response, SCardPCI receivePci) { /* The transmission system shall issue a GET RESPONSE command APDU (or TPDU) * to the card by assigning the minimum of SW2 and Le to parameter Le (or P3)). * Le = Le > 0 ? min(Le,SW2) : SW2 * http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_annex-a.aspx#AnnexA_4 */ var le = (commandApdu.Le > 0) && (commandApdu.Le < lastResponseApdu.SW2) ? commandApdu.Le : lastResponseApdu.SW2; var responseApdu = lastResponseApdu; do { // add the last ResponseAPDU to the Response object response.Add(responseApdu); response.Add(receivePci); var getResponseApdu = ConstructGetResponseApdu(ref le); // +2 bytes for status word var receiveBufferLength = le == 0 ? 256 + 2 : le + 2; var receiveBuffer = new byte[receiveBufferLength]; try { var sendBuffer = getResponseApdu.ToArray(); // Shall we wait until we re-send we APDU/TPDU? if (RetransmitWaitTime > 0) { Thread.Sleep(RetransmitWaitTime); } // send Command APDU again with new Le value responseApdu = SimpleTransmit( sendBuffer, sendBuffer.Length, getResponseApdu.Case, getResponseApdu.Protocol, receivePci, receiveBuffer, receiveBufferLength); } catch (WinErrorInsufficientBufferException ex) { throw new InvalidApduException($"GET RESPONSE command failed because of unsufficient buffer (Le={getResponseApdu.Le})", getResponseApdu, ex); } catch (InvalidOperationException ex) { throw new InvalidApduException( "Got SW1=0x61. Retransmission failed because of an invalid GET RESPONSE APDU.", getResponseApdu, ex); } // In case there is more data available. le = responseApdu.SW2; } while ( // More data available. responseApdu.SW1 == (byte)SW1Code.NormalDataResponse || // Warning condition: data may be corrupted. Iso7816-4 7.1.5 (responseApdu.SW1 == (byte)SW1Code.WarningNVDataNotChanged && responseApdu.SW2 == 0x81)); return(responseApdu); }
protected internal void AddResponseApdu(ResponseApdu apdu) { _lstRespApdu.Add(apdu); }
/// <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 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; }
///// <summary> ///// Select an applet based on its AID (Application IDentifier). As for now the AID should have a length of 11 bytes. ///// </summary> ///// <param name="AID">Application Identifier. An 11 byte array that represents the applet to select</param> private void SelectApplet(byte[] AID) { TS.TraceI("Start SelectApplet with ID \"{0}\".", Helper.ByteArrayToString(AID)); this.crdReader = GetReader(); byte[] pbRecvBuffer = new byte[256]; if (AID.Length != 0x0B) { throw new ArgumentException("Invalid length AID", "AID"); } //// Send SELECT Applet command byte[] selectApplet = new byte[] { 0x00, 0xA4, 0x04, 0x00, 0x0B, AID[0], AID[1], AID[2], AID[3], AID[4], AID[5], AID[6], AID[7], AID[8], AID[9], AID[10], 0x00 }; TS.TraceV("Select applet command: \"{0}\".", Helper.ByteArrayToString(selectApplet)); /////* //// 00 = Class //// A4 = Instructie //// 04 = P1 = Select Dedicated File (DF) //// 00 = P2 = File Control Information (FCI) //// 0B = lc = Lengte van de AID //// AID //// 00 = End ////*/ SCardError err = crdReader.Transmit(selectApplet, 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)) { throw new CardReaderException("Invalid response"); } TS.TraceI("End SelectApplet."); }
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(); }
static void Main(string[] args) { // Establish Smartcard context SCardContext ctx = new SCardContext(); ctx.Establish(SCardScope.System); string[] readernames = ctx.GetReaders(); if (readernames == null || readernames.Length < 1) throw new Exception("You need at least one reader in order to run this example."); // we will use the first reader for the transmit test. string readername = readernames[0]; SCardReader reader = new SCardReader(ctx); SCardError rc = reader.Connect( readername, SCardShareMode.Shared, SCardProtocol.Any); if (rc != SCardError.Success) { Console.WriteLine("Could not connect to card in reader " + readername + "\n" + "Error: " + SCardHelper.StringifyError(rc)); return; } // Build a GET CHALLENGE command CommandApdu apdu = new CommandApdu( IsoCase.Case2Short, reader.ActiveProtocol); apdu.CLA = 0x00; // Class apdu.INS = 0x84; // Instruction: GET CHALLENGE apdu.P1 = 0x00; // Parameter 1 apdu.P2 = 0x00; // Parameter 2 apdu.Le = 0x08; // Expected length of the returned data // convert the APDU object into an array of bytes byte[] cmd = apdu.ToArray(); // prepare a buffer for response APDU -> LE + 2 bytes (SW1 SW2) byte[] outbuf = new byte[apdu.ExpectedResponseLength]; rc = reader.Transmit( cmd, ref outbuf); if (rc == SCardError.Success) { Console.WriteLine("Ok."); if (outbuf != null) { ResponseApdu response = new ResponseApdu(outbuf, apdu.Case, apdu.Protocol); if (response.IsValid) { Console.WriteLine("SW1 SW2 = {0:X2} {1:X2}", response.SW1, response.SW2); if (response.HasData) { Console.Write("Data: "); for (int i = 0; i < (response.DataSize); i++) Console.Write("{0:X2} ", response.FullApdu[i]); Console.WriteLine(""); } } } } else { // Error Console.WriteLine(SCardHelper.StringifyError(rc)); } return; }
/// <summary> /// Creates a clone. /// </summary> /// <returns>A clone of the current instance.</returns> public virtual object Clone() { var tmp = new ResponseApdu { FullApdu = FullApdu, Length = Length }; return tmp; }
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 ResponseApdu _SimpleTransmit(byte[] cmdApdu, int cmdApduLength, IsoCase isoCase, SCardProtocol proto, SCardPCI recvPci, ref byte[] recvBuf, ref int recvBufLength) { SCardError sc = SCardError.UnknownError; bool cmdSent = false; do { // send Command APDU to the card sc = reader.Transmit( SCardPCI.GetPci(reader.ActiveProtocol), cmdApdu, cmdApduLength, recvPci, recvBuf, ref recvBufLength); // Do we need to resend the command APDU? if (sc == SCardError.InsufficientBuffer && recvBuf.Length < recvBufLength) { // The response buffer was too small. recvBuf = new byte[recvBufLength]; // Shall we wait until we re-send we APDU? if (_retransmitWaitTime > 0) Thread.Sleep(_retransmitWaitTime); } else cmdSent = true; } while (cmdSent == false); if (sc == SCardError.Success) { ResponseApdu respApdu = new ResponseApdu(recvBuf, recvBufLength, isoCase, proto); return respApdu; } // An error occurred, throw exception.. ThrowExceptionOnSCardError(sc); return null; }
public virtual Response Transmit(CommandApdu cmdApdu) { if (cmdApdu == null) { throw new ArgumentNullException("cmdApdu"); } // prepare send buffer (Check Command APDU and convert it to an byte array) byte[] sendbuf; try { sendbuf = cmdApdu.ToArray(); } catch (InvalidOperationException ex) { throw new InvalidApduException("Invalid APDU.", cmdApdu, ex); } catch (Exception ex) { throw ex; } // create Response object Response resp = new Response(); // prepare receive buffer (Response APDU) byte[] recvbuf = null; int recvbuflen = cmdApdu.ExpectedResponseLength; // expected size that shall be returned recvbuf = new byte[recvbuflen]; ResponseApdu respApdu = null; SCardPCI recvPci = new SCardPCI(); respApdu = _SimpleTransmit( sendbuf, sendbuf.Length, cmdApdu.Case, // ISO case used by the Command APDU cmdApdu.Protocol, // Protocol used by the Command APDU recvPci, ref recvbuf, ref recvbuflen); /* Check status word SW1SW2: * * 1. 0x6cxx -> Set response buffer size Le <- SW2 * 2. AND/OR 0x61xx -> More data can be read with GET RESPONSE */ // Case 1: SW1=0x6c, Previous Le/P3 not accepted -> Set le = SW2 if (respApdu.SW1 == (byte)SW1Code.ErrorP3Incorrect) { CommandApdu resendCmdApdu = (CommandApdu)cmdApdu.Clone(); if (respApdu.SW2 == 0) { resendCmdApdu.Le = 0; // 256 recvbuflen = 256 + 2; // 2 bytes for status word } else { resendCmdApdu.Le = respApdu.SW2; recvbuflen = respApdu.SW2 + 2; // 2 bytes for status word } recvbuf = new byte[recvbuflen]; recvPci = new SCardPCI(); try { sendbuf = resendCmdApdu.ToArray(); // Shall we wait until we re-send we APDU/TPDU? if (_retransmitWaitTime > 0) { Thread.Sleep(_retransmitWaitTime); } // send Command APDU again with new Le value respApdu = _SimpleTransmit( sendbuf, sendbuf.Length, resendCmdApdu.Case, resendCmdApdu.Protocol, recvPci, ref recvbuf, ref recvbuflen); } catch (InvalidOperationException ex) { throw new InvalidApduException("Got SW1=0x6c. Retransmission failed because of an invalid APDU.", resendCmdApdu, ex); } } // Case 2: SW1=0x61, More data available -> GET RESPONSE if (respApdu.SW1 == (byte)SW1Code.NormalDataResponse) { /* The transmission system shall issue a GET RESPONSE command APDU (or TPDU) * to the card by assigning the minimum of SW2 and Le to parameter Le (or P3)). * Le = min(Le,SW2) */ int _le = (cmdApdu.Le < respApdu.SW2) ? cmdApdu.Le : respApdu.SW2; do { // add the last ResponseAPDU to the Response object resp.AddResponseApdu(respApdu); resp.AddRecvPci(recvPci); CommandApdu getResponseApdu = _constructGetResponseApdu(ref _le); if (_le == 0) { recvbuflen = 256 + 2; // 2 bytes for status word } else { recvbuflen = _le + 2; // 2 bytes for status word } recvbuf = new byte[recvbuflen]; try { sendbuf = getResponseApdu.ToArray(); // Shall we wait until we re-send we APDU/TPDU? if (_retransmitWaitTime > 0) { Thread.Sleep(_retransmitWaitTime); } // send Command APDU again with new Le value respApdu = _SimpleTransmit( sendbuf, sendbuf.Length, getResponseApdu.Case, getResponseApdu.Protocol, recvPci, ref recvbuf, ref recvbuflen); } catch (InvalidOperationException ex) { throw new InvalidApduException("Got SW1=0x61. Retransmission failed because of an invalid GET RESPONSE APDU.", getResponseApdu, ex); } // In case there is more data available. _le = respApdu.SW2; } while ( // More data available. respApdu.SW1 == (byte)SW1Code.NormalDataResponse || // Warning condition: data may be corrupted. Iso7816-4 7.1.5 (respApdu.SW1 == (byte)SW1Code.WarningNVDataNotChanged && respApdu.SW2 == (byte)0x81) ); } resp.AddResponseApdu(respApdu); resp.AddRecvPci(recvPci); return(resp); }
/// <summary> /// Creates a clone. /// </summary> /// <returns>A clone of the current instance.</returns> public virtual object Clone() { var tmp = new ResponseApdu { _response = _response, _length = _length }; return tmp; }
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"; }