private void btnSend_Click(object sender, EventArgs e) { try { RespApdu respApdu = mPcscReader.Exchange(txtAPDU.Text); ml.NewLine(); ml.AddLine("Send: " + txtAPDU.Text); if (respApdu.Data != null && respApdu.Data.Length > 0) { //ml.AddLine("Resp: " + HexFormatting.ToHexString(respApdu.Data, true)); ml.AddLine(String.Format("Resp({0}B): {1}", respApdu.Data.Length, HexFormatting.ToHexString(respApdu.Data, true))); } else { ml.AddLine("Resp: (None)"); } ml.AddLine("Status: " + respApdu.SW1SW2.Value.ToString("X4")); txtMessage.Text = ml.Text; } catch (WinSCardException ex) { txtMessage.Text = ml.AddLine(ex.WinSCardFunctionName + " Error 0x" + ex.Status.ToString("X08") + ": " + ex.Message); } catch (Exception ex) { txtMessage.Text = ml.AddLine(ex.Message); } }
/// <summary> /// Convert byte sequence to HEX representation. /// </summary> /// <param name="bytes"></param> /// <param name="formatting">HEX string formatting.</param> /// <param name="upperCase">Should hex litteral be in upper case.</param> /// <returns>Formatted HEX representation of bytes.</returns> public static string ToHexString(this ArraySegment <byte> bytes, HexFormatting formatting = HexFormatting.Default, bool upperCase = true) { if (bytes == null) { throw new ArgumentNullException(nameof(bytes)); } var prefix = GetFilteredPrefixes(formatting).FirstOrDefault(); var offset = prefix?.Length ?? 0; var c = new char[offset + bytes.Count * 2]; for (var i = 0; i < offset; i++) { c[i] = prefix[i]; } byte b; var letterOffset = upperCase ? 0x37 : 0x57; const int digitOffset = 0x30; for (int bx = 0, cx = 0; bx < bytes.Count; ++bx, ++cx) { b = (byte)(bytes[bx] >> 4); c[offset + cx] = (char)(b > 9 ? b + letterOffset : b + digitOffset); b = (byte)(bytes[bx] & 0x0F); c[offset + (++cx)] = (char)(b > 9 ? b + letterOffset : b + digitOffset); } return(new string(c)); }
static void write_to_tag(String bytes_in) { string command = "FF D6 00 "; int byte_num = 0; int value; //string address = String.Format("{0:X}", value); String Hex_address; Byte[] Input_bytes = hex_string_to_byte_array(string_to_hex_string(bytes_in)); byte[] send_chunk = new byte[4]; RespApdu write_four_bytes; for (int i = 0; i < Input_bytes.Length; i = i + 4) { for (int j = 0; j < 4; j++) { if (j + i < Input_bytes.Length) { send_chunk[j] = Input_bytes[j + i]; } } value = Convert.ToInt32(byte_num); Hex_address = String.Format("{0:X}", value); command = command + Hex_address + " 04 " + HexFormatting.ToHexString(send_chunk, true); write_four_bytes = reader.Exchange(command); byte_num = byte_num + 1; } }
/// <summary> /// The SCardTransmit function sends a service request to the smart card and expects to receive data back from the card. /// </summary> /// <param name="sendBuffer"> /// The actual data to be written to the card. /// </param> /// <param name="sendLength"> /// The length, in bytes, of the sendBuffer parameter. /// </param> /// <param name="responseBuffer"> /// Returned data from the card. /// </param> /// <param name="responseLength"> /// Supplies the length, in bytes, of the responseBuffer parameter and receives the actual /// number of bytes received from the smart card. /// </param> public void Transmit(byte[] sendBuffer, int sendLength, byte[] responseBuffer, ref int responseLength) { SCARD_IO_REQUEST SCARD_PCI; SCARD_PCI.dwProtocol = (uint)activeSCardProtocol; SCARD_PCI.cbPciLength = 8; Trace.WriteLineIf(this.scardTrace, HexFormatting.Dump("--> C-APDU: 0x", sendBuffer, sendLength, 16, ValueFormat.HexASCII)); int ret = WinSCardAPIWrapper.SCardTransmit(phCARD, ref SCARD_PCI, sendBuffer, sendLength, IntPtr.Zero, responseBuffer, ref responseLength); if (ret == 0) { RespApdu respApdu = new RespApdu(responseBuffer, responseLength); Trace.WriteLineIf(scardTrace, respApdu.ToString()); } else { throw new WinSCardException(scardTrace, "SCard.Transmit", ret); } }
public byte[] RsReset() { try { RespApdu respApdu = mReader.Exchange("A4 0A 00 00 08"); // Get Random Number //Console.WriteLine("Random = 0x" + HexFormatting.ToHexString(respApdu.Data, true)); if (respApdu != null) { baRandom = respApdu.Data; strRandom = HexFormatting.ToHexString(baRandom, true); } else { baRandom = new byte[8]; Array.Clear(baRandom, 0, 8); } return(baRandom); } catch (WinSCardException ex) { //Console.WriteLine(ex.WinSCardFunctionName + " Error 0x" + // ex.Status.ToString("X08") + ": " + ex.Message); throw ex; } catch (Exception ex) { //Console.WriteLine(ex.Message); throw ex; } }
public void ConvertError(string input, HexFormatting formatting, string expectedError) { Assert.That(() => HexEncodingExtensions.FromHexString(input, formatting), Throws.Exception .InstanceOf <ArgumentException>() .With.Message.EqualTo(expectedError)); }
public void Convert(string input, HexFormatting formatting, string expected) { var bytes = HexEncodingExtensions.FromHexString(input, formatting); var actual = HexEncodingExtensions.ToHexString(bytes, formatting); Assert.AreEqual(expected, actual); }
public static string cardProtocol() { WinSCard scard = new WinSCard(); try { scard.EstablishContext(); scard.ListReaders(); string readerName = scard.ReaderNames[1]; scard.WaitForCardPresent(readerName); scard.Connect(readerName); byte[] cmdApdu = { 0xFF, 0xCA, 0x00, 0x00, 00 }; // Get Card UID ... byte[] respApdu = new byte[10]; int respLength = respApdu.Length; scard.Transmit(cmdApdu, cmdApdu.Length, respApdu, ref respLength); //find a better place for this App.UID = HexFormatting.ToHexString(respApdu, true); //he wanted some kinda beeping sound when someone swipes their card System.Media.SystemSounds.Beep.Play(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } return(App.UID); }
/// <summary> /// The SCardGetAttrib function gets the current reader attributes. /// It does not affect the state of the reader, driver, or card. /// </summary> /// <param name="attrId"> /// Identifier for the attribute to get. /// </param> /// <param name="responseBuffer"> /// The response buffer. /// </param> /// <param name="responseLength"> /// Supplies the length of the responseBuffer in bytes, and receives the actual length /// of the received attribute. /// </param> public void GetAttrib(uint attrId, byte[] responseBuffer, ref int responseLength) { Trace.WriteLineIf(this.scardTrace, string.Format(" SCard.SCardGetAttrib(AttrId: {0})", (SCARD_ATTR)attrId)); int ret = WinSCardAPIWrapper.SCardGetAttrib(phCARD, (uint)attrId, responseBuffer, ref responseLength); if (ret == 0) { Trace.WriteLineIf(this.scardTrace, HexFormatting.Dump(" Attr. Value: 0x", responseBuffer, responseLength, 16, ValueFormat.HexASCII)); } else { throw new WinSCardException(scardTrace, "SCard.Control", ret); } }
/// <summary> /// The SCardReconnect function reestablishes an existing connection between the calling application and /// a smart card. This function moves a card handle from direct access to general access, or acknowledges /// and clears an error condition that is preventing further access to the card. /// </summary> /// <param name="dwShareMode"> /// A flag that indicates whether other applications may form connections to the card. /// </param> /// <param name="dwPrefProtocol"> /// A bitmask of acceptable protocols for the connection. Possible values may be combined with the OR operation. /// </param> /// <param name="disconnectAction"> /// Action to take on the card in the connected reader on close. /// </param> /// <returns> /// If the function succeeds, the function returns SCARD_S_SUCCESS. /// If the function fails, it returns an error code. /// </returns> public void Reconnect(SCARD_SHARE_MODE dwShareMode, SCARD_PROTOCOL dwPrefProtocol, SCARD_DISCONNECT disconnectAction) { int ret = WinSCardAPIWrapper.SCardReconnect(phCARD, (uint)dwShareMode, (uint)dwPrefProtocol, (uint)disconnectAction, out activeSCardProtocol); if (ret == 0) { Trace.WriteLineIf(scardTrace, String.Format(" SCard.Reconnect(SHARE_MODE.{0}, SCARD_PROTOCOL.{1}, SCARD_DISCONNECT.{2} )", dwShareMode, (SCARD_PROTOCOL)dwPrefProtocol, (SCARD_DISCONNECT)disconnectAction)); Trace.WriteLineIf(scardTrace, String.Format(" Active Protocol: SCARD_PROTOCOL.{0} ", (SCARD_PROTOCOL)activeSCardProtocol)); Trace.WriteLineIf(this.TraceSCard, HexFormatting.Dump(" ATR: 0x", this.Atr, this.Atr.Length, 24)); } else { throw new WinSCardException(scardTrace, "SCard.Reconnect", ret); } }
/// <summary> /// The SCardConnect function establishes a connection (using a specific resource manager context) /// between the calling application and a smart card contained by a specific reader. /// If no card exists in the specified reader, an error is returned. /// </summary> /// <param name="szReader"> /// The name of the reader that contains the target card. /// </param> /// <param name="dwShareMode"> /// A flag that indicates whether other applications may form connections to the card. /// </param> /// <param name="dwPrefProtocol"> /// A bitmask of acceptable protocols for the connection. Possible values may be combined with the OR operation. /// </param> public void Connect(string szReader, SCARD_SHARE_MODE dwShareMode, SCARD_PROTOCOL dwPrefProtocol) { int ret = WinSCardAPIWrapper.SCardConnect(phContext, szReader, (uint)dwShareMode, (uint)dwPrefProtocol, out phCARD, out activeSCardProtocol); if (ret == 0) { connectedReaderName = szReader; Trace.WriteLineIf(scardTrace, String.Format(" SCard.Connect({0}, SHARE_MODE.{1}, SCARD_PROTOCOL.{2})", szReader, dwShareMode, (SCARD_PROTOCOL)dwPrefProtocol)); Trace.WriteLineIf(scardTrace, String.Format(" Active Protocol: SCARD_PROTOCOL.{0} ", (SCARD_PROTOCOL)activeSCardProtocol)); Trace.WriteLineIf(this.TraceSCard, HexFormatting.Dump(" ATR: 0x", this.Atr, this.Atr.Length, 24)); } else { connectedReaderName = null; throw new WinSCardException(scardTrace, "SCard.Connect", ret); //Trace.WriteLineIf(pcscTrace, String.Format(" Error: SCardConnect failed with 0x{0:X8}.", ret)); } }
private static byte[] InternalConvert(string str, HexFormatting formatting, int offset, int count) { if (str == null) { throw new ArgumentNullException(nameof(str)); } offset = offset < 0 ? 0 : offset; count = count < 0 ? str.Length : count; var prefix = GetFilteredPrefixes(formatting).FirstOrDefault(x => str.StartsWith(x)); if (prefix != null) { offset += prefix.Length; count -= prefix.Length; } else if (!formatting.HasFlag(HexFormatting.None)) { throw new ArgumentOutOfRangeException(nameof(str), "Invalid hex format."); } if (count % 2 != 0) { throw new ArgumentOutOfRangeException(nameof(str), "Invalid hex length."); } if (count == 0) { return(Array.Empty <byte>()); } var buffer = new byte[count / 2]; for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx) { buffer[bx] = (byte)(GetNibble(str[sx + offset]) << 4); buffer[bx] |= (byte)GetNibble(str[++sx + offset]); } return(buffer); }
public static async Task Read() { PCSCReader reader = new PCSCReader(); while (true) { try { reader.Connect(); reader.ActivateCard(); RespApdu respApdu = reader.Exchange("FF CA 00 00 00"); // Get Card UID ... if (respApdu.SW1SW2 == 0x9000) { InvokeScanned("0x" + HexFormatting.ToHexString(respApdu.Data, false)); await Task.Delay(1000); } } catch (WinSCardException ex) { InvokeError(ex.WinSCardFunctionName + " Error 0x" + ex.Status.ToString("X08") + ": " + ex.Message); await Task.Delay(1000); } catch (Exception ex) { InvokeError(ex.Message); await Task.Delay(1000); } finally { reader.Disconnect(); } } }
/// <summary> /// The SCardControl function gives you direct control of the reader. /// You can call it any time after a successful call to SCardConnect and before /// a successful call to SCardDisconnect. The effect on the state of the reader /// depends on the control code. /// </summary> /// <param name="dwControlCode"> /// Control code for the operation. This value identifies the specific operation to be performed. /// </param> /// <param name="inBuffer"> /// A buffer that contains the data required to perform the operation. /// This parameter can be null if the dwControlCode parameter specifies an operation that does /// not require input data. /// </param> /// <param name="inBufferLength"> /// Length of the input buffer. /// </param> /// <param name="outBuffer"> /// The output buffer. /// </param> /// <param name="outBufferSize"> /// Size, in bytes, of the output buffer. /// </param> /// <param name="bytesReturned"> /// Supplies the length, in bytes, of the outBuffer parameter. /// </param> public void Control(uint dwControlCode, byte[] inBuffer, int inBufferLength, byte[] outBuffer, int outBufferSize, ref int bytesReturned) { Trace.WriteLineIf(this.scardTrace, string.Format(" SCard.Control (Cntrl Code: 0x{0:X}", dwControlCode)); //Trace.WriteLineIf( this.scardTrace, HexFormatting.Dump(string.Format( "--> SCard.Control (Cntrl Code: 0x{0:X} ): 0x", // dwControlCode ), inBuffer, inBufferLength, 16, ValueFormat.HexASCII ) ); int ret = WinSCardAPIWrapper.SCardControl(phCARD, dwControlCode, inBuffer, inBufferLength, outBuffer, outBufferSize, ref bytesReturned); if (ret == 0) { Trace.WriteLineIf(this.scardTrace, HexFormatting.Dump(" Value: 0x", outBuffer, bytesReturned, 16, ValueFormat.HexASCII)); } else { throw new WinSCardException(scardTrace, "SCard.Control", ret); } }
public byte[] GetRandom() { try { RespApdu respApdu = mReader.Exchange("A4 0A 00 00 08"); // Get Random Number //Console.WriteLine("Random = 0x" + HexFormatting.ToHexString(respApdu.Data, true)); //if (respApdu != null && respApdu.Data != null) if (respApdu.SW1SW2 == 0x9000) { baRandom = respApdu.Data; strRandom = HexFormatting.ToHexString(baRandom, true); } else { //baRandom = new byte[8]; //Array.Clear(baRandom, 0, 8); //return null; ushort sw = respApdu.SW1SW2 ?? 0; throw new Exception("GetRandom has not supported. Card's SW = " + sw.ToString("X4")); } //strRandom = HexFormatting.ToHexString(baRandom, true); return(baRandom); } catch (WinSCardException ex) { //Console.WriteLine(ex.WinSCardFunctionName + " Error 0x" + // ex.Status.ToString("X08") + ": " + ex.Message); throw ex; } catch (Exception ex) { //Console.WriteLine(ex.Message); throw ex; } }
/*<summary> * BYTE[] find_ndef() * This function returns Byte array containgin all bytes from * starting byte of NDEF "D1" record to the termination byte "FE" *</summary> * * <remarks> * This function is naive and only tries to find the content * delimited by start and terminating bytes of NDEF:s * </remarks> * * */ static Byte[] find_ndef() { RespApdu read_four_bytes; int byte_num = 0; String command; String Hex_address; int value; var allbytes = new List <string>(); //Used for easy appending of all found bytes var hexbytes = new List <byte>(); while (true) { value = Convert.ToInt32(byte_num); Hex_address = String.Format("{0:X}", value); //RespApdu only accepts commands that are of type //"XX XX XX XX XX" so zero has to be prepended //for values smaller than 0x10 if (byte_num < 16) { Hex_address = "0" + Hex_address; } //We start from block 0 byte 0 //Reading command: "FF B0 00 XX YY" //XX is reading address //YY is amount of bytes to read //Distance between each XX is 04 command = "FF B0 00 " + Hex_address + " 04"; read_four_bytes = reader.Exchange(command); if (read_four_bytes.SW1SW2 != 0x9000) { Console.WriteLine("Reading bytes from the NFC tag failed. reader returned: ", HexFormatting.ToHexString(read_four_bytes.Data, true)); break; } allbytes.Add(HexFormatting.ToHexString(read_four_bytes.Data, true)); hexbytes.AddRange(read_four_bytes.Data); if (HexFormatting.ToHexString(read_four_bytes.Data, true).Contains("FE")) { Console.WriteLine("End of NDEF found"); break; } byte_num = byte_num + 1; } foreach (Object obj in hexbytes) { Console.Write(" {0}", String.Format("{0:X}", obj)); } Console.WriteLine(); for (int i = 0; i < hexbytes.Count; i++) { //This IS D1 in hex. It starts NDEF tags if (hexbytes[i] == 209) { hexbytes.RemoveRange(0, i); } else if (hexbytes[i] == 254) { break; } } return(hexbytes.ToArray()); }
/// <summary> /// Convert byte sequence to HEX representation. /// </summary> /// <param name="bytes"></param> /// <param name="formatting">HEX string formatting.</param> /// <param name="upperCase">Should hex litteral be in upper case.</param> /// <returns>Formatted HEX representation of bytes.</returns> public static string ToHexString(this byte[] bytes, HexFormatting formatting = HexFormatting.Default, bool upperCase = true) { return(ToHexString((ArraySegment <byte>)bytes, formatting, upperCase)); }
private static IEnumerable <string> GetFilteredPrefixes(HexFormatting formatting) { var bitMap = (uint)formatting; return(PossiblePrefixes.Where((x, i) => (bitMap & (1 << (i + 1))) != 0)); }
/// <summary> /// Convert HEX representation to byte array. /// </summary> /// <param name="str">Input string.</param> /// <param name="offset">Starting position in string.</param> /// <param name="count">Count of characters in string.</param> /// <param name="formatting"></param> /// <returns></returns> public static byte[] FromHexString(this string str, int offset, int count, HexFormatting formatting = HexFormatting.Default) { return(InternalConvert(str, formatting, offset, count)); }
/// <summary> /// Convert HEX representation to byte array. /// </summary> /// <param name="str">Input string.</param> /// <param name="formatting"></param> /// <returns></returns> public static byte[] FromHexString(this string str, HexFormatting formatting = HexFormatting.Default) { return(InternalConvert(str, formatting, -1, -1)); }
static void Main(string[] args) { ConsoleTraceListener consoleTraceListener = new ConsoleTraceListener(); Trace.Listeners.Add(consoleTraceListener); reader = new PCSCReader(); //NdefLibrary.Ndef.NdefMessage message = new NdefLibrary.Ndef.NdefMessage(); /*WinSCard testi = new WinSCard(); * testi.Connect(null);*/ string input_text = ""; while (input_text != "joo") { try { //reader.SCard.Connect("",SCARD_SHARE_MODE.Direct, SCARD_PROTOCOL.Tx); reader.Connect(); //set_buzzer_on(); //set_target_mode(); reader.ActivateCard(); //WinSCard reader = new WinSCard(); //testi.Connect(null); //For some reason Direct commands only work after card has been activated (the command above) //Also the reader resets to normal state after it's been unplugged. //TODO: check if mode changes can be made permanent if (!modes_changed) { //Console.WriteLine("YOLOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"); //change_modes_for_reader(); modes_changed = true; } RespApdu respApdu = reader.Exchange(APDU_commands["get_card_uid"]); // Get Card UID ... if (respApdu.SW1SW2 == 0x9000) { Console.WriteLine("UID = 0x" + HexFormatting.ToHexString(respApdu.Data, true)); } use_stuff_properly(); //RespApdu tespApdu = reader.Exchange(String.Format(APDU_commands["direct_command_prefix"],"18", "D4 86 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00")); // Get Card UID ... //RespApdu bespApdu = reader.Exchange(String.Format(APDU_commands["direct_command_prefix"], "18", "D4 40 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00")); // Get Card UID ... //message = NdefLibrary.Ndef.NdefMessage.FromByteArray(); //message = NdefLibrary.Ndef.NdefMessage.FromByteArray(find_ndef()); //parse_record(message); //write_to_tag("meloonis"); } catch (WinSCardException ex) { Console.WriteLine(ex.WinSCardFunctionName + " Error 0x" + ex.Status.ToString("X08") + ": " + ex.Message); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { reader.Disconnect(); Console.WriteLine("Please press any key..."); input_text = Console.ReadLine(); } } }
//Currently this writes plaintext to tag in NDEF format //TODO: Other tag types // Limit to how much data can be fit to tag static void write_to_tag(String bytes_in) { string command_prefix = "FF D6 00 "; string command; String Hex_address; NdefMessage write_this = new NdefMessage { new NdefUriRecord { Uri = bytes_in } }; byte[] ndef_prefix = { 0x03, (byte)write_this.ToByteArray().Length }; List <byte> concat = new List <byte>(); concat.AddRange(ndef_prefix); concat.AddRange(write_this.ToByteArray()); byte[] ndef_bytes = concat.ToArray(); foreach (var item in ndef_bytes) { Console.WriteLine(HexFormatting.ToHexString(item)); } //Byte[] Input_bytes = hex_string_to_byte_array(string_to_hex_string(bytes_in)); byte[] send_chunk = new byte[4]; RespApdu write_four_bytes; int count = 0; int mod4 = ndef_bytes.Length % 4; for (int i = 0; i < ndef_bytes.Length; ++i) { send_chunk[count] = ndef_bytes[i]; ++count; if (count == 4) { count = 0; Hex_address = String.Format("{0:X}", Convert.ToInt32((i / 4) + 4)); if ((i / 4) + 4 < 16) { Hex_address = "0" + Hex_address; } Console.WriteLine(Hex_address); command = command_prefix + Hex_address + " 04 " + HexFormatting.ToHexString(send_chunk, true); Console.WriteLine(command); write_four_bytes = reader.Exchange(command); } } if (count != 0) { for (int i = count; i < send_chunk.Length; i++) { send_chunk[i] = 0x00; } send_chunk[2] = 254; Hex_address = String.Format("{0:X}", Convert.ToInt32(((ndef_bytes.Length - count) / 4) + 4)); if ((((ndef_bytes.Length - count) / 4) + 4) < 16) { Hex_address = "0" + Hex_address; } command = command_prefix + Hex_address + " 04 " + HexFormatting.ToHexString(send_chunk, true); write_four_bytes = reader.Exchange(command); } //command = command + "04" + " 04 " + hexString; //write_four_bytes = reader.Exchange(command); /*if (Input_bytes.Length % 4 != 0) * { * int mod_of_input = Input_bytes.Length % 4; * for (int i = 0; i < mod_of_input; i++) * { * * * } * }*/ /* * for (int i = 0; i < Input_bytes.Length; i = i + 4) * { * for (int j = 0; j < 4; j++) * { * if (j + i < Input_bytes.Length) * { * send_chunk[j] = Input_bytes[j + i]; * } * } * * value = Convert.ToInt32(byte_num); * Hex_address = String.Format("{0:X}", value); * command = command + Hex_address + " 04 " + HexFormatting.ToHexString(send_chunk, true); * write_four_bytes = reader.Exchange(command); * byte_num = byte_num + 1; * }*/ }