//this method will open a reader instance and read the nfc device with //cmd as its input and the command to run. it will return a string of the result. //@params cmd - the command to run private string readNFC(CmdApdu cmd) { PCSCReader reader = new PCSCReader(); string payload = ""; try { reader.Connect(); reader.ActivateCard(GS.SCard.Const.SCARD_SHARE_MODE.Exclusive, GS.SCard.Const.SCARD_PROTOCOL.Tx); RespApdu respApdu = reader.Exchange(cmd, 0x9000); if (respApdu.SW1SW2 == 0x9000) { payload = Encoding.UTF8.GetString(respApdu.Data); } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { reader.Disconnect(); } return(payload); }
private void btnConnect_Click(object sender, EventArgs e) { string readerName = (string)comboReaders.SelectedItem; try { mPcscReader.Connect(readerName); mPcscReader.ActivateCard(); txtATR.Text = mPcscReader.SCard.AtrString; txtProtocol.Text = mPcscReader.SCard.SCardProtocol.ToString(); lblProtocol.Visible = true; IsReaderConnected = true; btnConnect.Enabled = false; btnDisconnect.Enabled = true; btnSend.Enabled = true; txtMessage.Text = ml.AddLine("IsCardPresent = " + mPcscReader.SCard.IsCardPresent); } catch (Exception ex) { mPcscReader.Disconnect(); ml.AddLine(ex.ToString()); txtMessage.Text = ml.AddLine("卡片連接失敗, 請檢查卡片是否己正確插入讀卡機"); } }
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(); } } }
private void ReadCard(object o) { UseHourglass(true); string selectedReader = o as string; UpdateStatusLabel("Reading card..."); TreeView treeView = new TreeView(); TreeNode cardNode = new TreeNode("Card"); cardNode.ImageIndex = 0; cardNode.SelectedImageIndex = 0; treeView.Nodes.Add(cardNode); // Tree nodes TreeNode pseNode = null; TreeNode fciNode = null; ASN1 fci = null; List <byte[]> pseIdentifiers = new List <byte[]>(); List <byte[]> applicationIdentifiers = new List <byte[]>(); ASCIIEncoding encoding = new ASCIIEncoding(); APDUCommand apdu = null; APDUResponse response = null; bool pseFound = false; if (!skipPSEToolStripMenuItem.Checked) { pseIdentifiers.Add(encoding.GetBytes("1PAY.SYS.DDF01")); pseIdentifiers.Add(encoding.GetBytes("2PAY.SYS.DDF01")); } try { // Now lets process all Payment System Environments if (pseIdentifiers.Count > 0) { cardReader.Connect(selectedReader); foreach (byte[] pse in pseIdentifiers) { apdu = new APDUCommand(0x00, 0xA4, 0x04, 0x00, pse, (byte)pse.Length); response = cardReader.Transmit(apdu); // Get response nescesary if (response.SW1 == 0x61) { apdu = new APDUCommand(0x00, 0xC0, 0x00, 0x00, null, response.SW2); response = cardReader.Transmit(apdu); } // PSE application read found ok if (response.SW1 == 0x90) { pseFound = true; pseNode = new TreeNode(String.Format("Application {0}", encoding.GetString(pse))); pseNode.ImageIndex = 1; pseNode.SelectedImageIndex = 1; pseNode.Tag = pse; cardNode.Nodes.Add(pseNode); fciNode = new TreeNode("File Control Information"); fciNode.ImageIndex = 3; fciNode.SelectedImageIndex = 3; fciNode.Tag = "fci"; pseNode.Nodes.Add(fciNode); fci = new ASN1(response.Data); AddRecordNodes(fci, fciNode); byte sfi = new ASN1(response.Data).Find(0x88).Value[0]; byte recordNumber = 0x01; byte p2 = (byte)((sfi << 3) | 4); TreeNode efDirNode = new TreeNode(String.Format("EF Directory - {0:X2}", sfi)); efDirNode.ImageIndex = 2; efDirNode.SelectedImageIndex = 2; efDirNode.Tag = sfi; pseNode.Nodes.Add(efDirNode); while (response.SW1 != 0x6A && response.SW2 != 0x83) { apdu = new APDUCommand(0x00, 0xB2, recordNumber, p2, null, 0x00); response = cardReader.Transmit(apdu); // Retry with correct length if (response.SW1 == 0x6C) { apdu = new APDUCommand(0x00, 0xB2, recordNumber, p2, null, response.SW2); response = cardReader.Transmit(apdu); } if (response.SW1 == 0x61) { apdu = new APDUCommand(0x00, 0xC0, 0x00, 0x00, null, response.SW2); response = cardReader.Transmit(apdu); } if (response.Data != null) { TreeNode recordNode = new TreeNode(String.Format("Record - {0:X2}", recordNumber)); recordNode.ImageIndex = 4; recordNode.SelectedImageIndex = 4; recordNode.Tag = recordNumber; efDirNode.Nodes.Add(recordNode); ASN1 aef = new ASN1(response.Data); AddRecordNodes(aef, recordNode); foreach (ASN1 appTemplate in aef) { // Check we really have an Application Template if (appTemplate.Tag[0] == 0x61) { applicationIdentifiers.Add(appTemplate.Find(0x4f).Value); } } } recordNumber++; } } if (pseFound) { break; } } cardReader.Disconnect(); } // We couldn't read the AID's from the PSE, so we'll just try querying all ADI's we know about if (!pseFound) { // From http://www.darkc0de.com/others/ChAP.py applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003")); // VISA applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000031010")); // VISA Debit/Credit applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003101001")); // VISA Credit applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003101002")); // VISA Debit applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000032010")); // VISA Electron applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000033010")); // VISA Interlink applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000038010")); // VISA Plus applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000003999910")); // VISA ATM applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000041010")); // Mastercard applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000048010")); // Cirrus applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000043060")); // Maestro applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000050001")); // Maestro UK applicationIdentifiers.Add(Helpers.HexStringToBytes("A00000002401")); // Self Service applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000025")); // American Express applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000025010104")); // American Express applicationIdentifiers.Add(Helpers.HexStringToBytes("A000000025010701")); // ExpressPay applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000291010")); // Link applicationIdentifiers.Add(Helpers.HexStringToBytes("B012345678")); // Maestro TEST applicationIdentifiers.Add(Helpers.HexStringToBytes("A0000000651010")); // JCB } // Now lets process all of the AID's we found if (applicationIdentifiers.Count > 0) { foreach (byte[] AID in applicationIdentifiers) { List <ApplicationFileLocator> applicationFileLocators = new List <ApplicationFileLocator>(); StringBuilder sb = new StringBuilder(); cardReader.Connect(selectedReader); // Select AID apdu = new APDUCommand(0x00, 0xA4, 0x04, 0x00, AID, (byte)AID.Length); response = cardReader.Transmit(apdu); // Get response nescesary if (response.SW1 == 0x61) { apdu = new APDUCommand(0x00, 0xC0, 0x00, 0x00, null, response.SW2); response = cardReader.Transmit(apdu); } // Application not found if (response.SW1 == 0x6A && response.SW2 == 0x82) { continue; } if (response.SW1 == 0x90) { foreach (byte b in AID) { sb.AppendFormat("{0:X2}", b); } TreeNode applicationNode = new TreeNode(String.Format("Application {0}", sb.ToString())); applicationNode.ImageIndex = 1; applicationNode.SelectedImageIndex = 1; applicationNode.Tag = AID; cardNode.Nodes.Add(applicationNode); fciNode = new TreeNode("File Control Information"); fciNode.ImageIndex = 3; fciNode.SelectedImageIndex = 3; fciNode.Tag = "fci"; applicationNode.Nodes.Add(fciNode); fci = new ASN1(response.Data); AddRecordNodes(fci, fciNode); // Get processing options (with empty PDOL) apdu = new APDUCommand(0x80, 0xA8, 0x00, 0x00, new byte[] { 0x83, 0x00 }, 0x02); response = cardReader.Transmit(apdu); // Get response nescesary if (response.SW1 == 0x61) { apdu = new APDUCommand(0x00, 0xC0, 0x00, 0x00, null, response.SW2); response = cardReader.Transmit(apdu); } if (response.SW1 == 0x90) { ASN1 template = new ASN1(response.Data); ASN1 aip = null; ASN1 afl = null; // Primative response (Template Format 1) if (template.Tag[0] == 0x80) { byte[] tempAIP = new byte[2]; Buffer.BlockCopy(template.Value, 0, tempAIP, 0, 2); aip = new ASN1(0x82, tempAIP); byte[] tempAFL = new byte[template.Length - 2]; Buffer.BlockCopy(template.Value, 2, tempAFL, 0, template.Length - 2); afl = new ASN1(0x94, tempAFL); } // constructed data object response (Template Format 2) if (template.Tag[0] == 0x77) { aip = template.Find(0x82); afl = template.Find(0x94); } // Chop up AFL's for (int i = 0; i < afl.Length; i += 4) { byte[] AFL = new byte[4]; Buffer.BlockCopy(afl.Value, i, AFL, 0, 4); ApplicationFileLocator fileLocator = new ApplicationFileLocator(AFL); applicationFileLocators.Add(fileLocator); } TreeNode aipaflNode = new TreeNode("Application Interchange Profile - Application File Locator"); aipaflNode.ImageIndex = 3; aipaflNode.SelectedImageIndex = 3; aipaflNode.Tag = "aip"; applicationNode.Nodes.Add(aipaflNode); ASN1 aipafl = new ASN1(response.Data); AddRecordNodes(aipafl, aipaflNode); foreach (ApplicationFileLocator file in applicationFileLocators) { int r = file.FirstRecord;// +afl.OfflineRecords; // We'll read SDA records too int lr = file.LastRecord; byte p2 = (byte)((file.SFI << 3) | 4); TreeNode efNode = new TreeNode(String.Format("Elementary File - {0:X2}", file.SFI)); efNode.ImageIndex = 2; efNode.SelectedImageIndex = 2; efNode.Tag = file.SFI; applicationNode.Nodes.Add(efNode); while (r <= lr) { apdu = new APDUCommand(0x00, 0xB2, (byte)r, p2, null, 0x00); response = cardReader.Transmit(apdu); // Retry with correct length if (response.SW1 == 0x6C) { apdu = new APDUCommand(0x00, 0xB2, (byte)r, p2, null, response.SW2); response = cardReader.Transmit(apdu); } TreeNode recordNode = new TreeNode(String.Format(" Record - {0:X2}", r)); if (r <= file.OfflineRecords) { recordNode.ImageIndex = 5; recordNode.SelectedImageIndex = 5; } else { recordNode.ImageIndex = 4; recordNode.SelectedImageIndex = 4; } recordNode.Tag = r; efNode.Nodes.Add(recordNode); ASN1 record = new ASN1(response.Data); AddRecordNodes(record, recordNode); r++; } } //IEnumerable<XElement> tags = tagsDocument.Descendants().Where(el => el.Name == "Tag"); //foreach (XElement element in tags) //{ // string tag = element.Attribute("Tag").Value; // // Only try GET_DATA on two byte tags // if (tag.Length == 4) // { // byte p1 = byte.Parse(tag.Substring(0, 2), NumberStyles.HexNumber); // byte p2 = byte.Parse(tag.Substring(2, 2), NumberStyles.HexNumber); // apdu = new APDUCommand(0x80, 0xCA, p1, p2, null, 0); // response = cardReader.Transmit(apdu); // if (response.SW1 == 0x90) // { // Debug.WriteLine(response.ToString()); // } // } //} apdu = new APDUCommand(0x80, 0xCA, 0x9f, 0x13, null, 0); response = cardReader.Transmit(apdu); Debug.WriteLine(response.ToString()); apdu = new APDUCommand(0x80, 0xCA, 0x9f, 0x17, null, 0); response = cardReader.Transmit(apdu); Debug.WriteLine(response.ToString()); apdu = new APDUCommand(0x80, 0xCA, 0x9f, 0x36, null, 0); response = cardReader.Transmit(apdu); Debug.WriteLine(response.ToString()); } else { // Unexpected status word UpdateStatusLabel(String.Format("Unexpected response from GET PROCESSING OPTIONS command: 0x{0:X2}{1:X2}", response.SW1, response.SW2)); } } else { // Unexpected status word UpdateStatusLabel(String.Format("Unexpected response from SELECT command: 0x{0:X2}{1:X2}", response.SW1, response.SW2)); } cardReader.Disconnect(); } } treeViewData.Invoke(new UpdateTreeViewDelegate(UpdateTreeView), new object[] { treeView }); } catch (PCSCException ex) { UpdateStatusLabel(ex.Message); return; } finally { UseHourglass(false); UpdateStatusLabel("Ready"); } }
static void Main(string[] args) { try { System.IO.StreamReader file = new System.IO.StreamReader("settings.txt"); reader_name = file.ReadLine(); //Console.WriteLine("SETTINGSFILE CONTENT: " + reader_name); } catch (System.IO.FileNotFoundException) { System.Environment.Exit(1); } ConsoleTraceListener consoleTraceListener = new ConsoleTraceListener(); Trace.Listeners.Add(consoleTraceListener); reader = new PCSCReader(); NdefLibrary.Ndef.NdefMessage message = new NdefLibrary.Ndef.NdefMessage(); //string input_text = ""; //while (input_text != "joo") //{ try { //turn_on_antenna(); //reader.SCard.Connect("",SCARD_SHARE_MODE.Direct, SCARD_PROTOCOL.Tx); //reader.Connect(); //reader.ActivateCard(); //set_buzzer_on(); //set_target_mode(); if (args[0] == "read") { //Console.WriteLine("Initing stuff"); //reader.SCard.Connect(reader.SCard.ListReaders()[1], SCARD_SHARE_MODE.Direct, SCARD_PROTOCOL.Default); //Console.WriteLine(reader.SCard.GetSCardCtlCode(3500)); reader.Connect(reader_name); Console.WriteLine(reader.SCard.ListReaders()[0]); reader.ActivateCard(SCARD_SHARE_MODE.Shared, SCARD_PROTOCOL.T1); turn_on_antenna(); message = NdefLibrary.Ndef.NdefMessage.FromByteArray(find_ndef()); Console.WriteLine("rd: " + parse_record(message)); //Console.WriteLine("Please press any key..."); //string input_text = Console.ReadLine(); //turn_off_antenna(); } else if (args[0] == "write" && args.Length == 2) { Console.WriteLine("writing to tag: ", args[1]); reader.Connect(); reader.ActivateCard(SCARD_SHARE_MODE.Shared, SCARD_PROTOCOL.T1); turn_on_antenna(); write_to_tag(args[1]); Console.WriteLine("wrote to tag:" + args[1]); } else if (args[0] == "list") { Console.WriteLine(reader.SCard.ListReaders()); System.Environment.Exit(1); } else { Console.WriteLine("Bad arguments"); reader.SCard.Disconnect(); System.Environment.Exit(1); } //WinSCard yhteys = new WinSCard(); //yhteys.Connect(yhteys.ListReaders()[0]); //yhteys.Control(0, hex_string_to_byte_array(APDU_commands[]), ); //write_to_tag(input_text = "Hassulla Tassulla kiva paijaa massua ai että kun on hassua:3"); //reader.ActivateCard(); //try_this(); //set_initiator_mode(); //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 //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)); * }*/ //message = NdefLibrary.Ndef.NdefMessage.FromByteArray(find_ndef()); //parse_record(message); //set_initiator_mode(); //string input_text = Console.ReadLine(); //System.Environment.Exit(1); } catch (WinSCardException ex) { Console.WriteLine(ex.WinSCardFunctionName + " Error 0x" + ex.Status.ToString("X08") + ": " + ex.Message); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { //direct_command(APDU_commands["enable_picc_polling"]); //turn_off_antenna(); //Console.WriteLine("Please press any key..."); //string input_text = Console.ReadLine(); turn_off_antenna(); reader.SCard.Disconnect(); System.Environment.Exit(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(); } } }