public void ReadCard() { //get processing options ReadGPO(); //read all possible data and extract needed info foreach (SFIRecords sfir in sfiRecords) { byte p2 = (byte)((sfir.sfi << 3) | 4); foreach (byte p1 in sfir.records) { //read each record APDUCommand apduReadRecord = new APDUCommand(0x00, 0xB2, p1, p2, null, 0); APDUResponse apduR = this.cardUpdater.Transmit(apduReadRecord); if (apduR.SW1 == 0x90) { if (apduR.Data[0] == 0x70 || apduR.Data[0] == 0x77) { ExtractData(ReadTagData(apduR.Data, 0)); //if (!String.IsNullOrEmpty(NumberString) && !String.IsNullOrEmpty(Name) && // !String.IsNullOrEmpty(ExpiryString) && !String.IsNullOrEmpty(CardType) && // !String.IsNullOrEmpty(Label)) // return; //we have all info we need } else { throw new Exception("Unrecognized data template"); } } } } }
public bool SelectApplication() { System.Threading.Thread.Sleep(100); //dunno what the heck is this command APDUCommand apduCmd = new APDUCommand(0, 0xa4, 1, 0, new byte[] { 1, 0x18 }, 0); APDUResponse apdu1 = iCard.Transmit(apduCmd); if (apdu1.SW1 != 0x90) { System.Threading.Thread.Sleep(100); apdu1 = iCard.Transmit(apduCmd); if (apdu1.SW1 != 0x90) { return(false); } } System.Threading.Thread.Sleep(100); //dunno what the heck is this command, probably selecting something apduCmd = new APDUCommand(0, 0xa4, 2, 0, new byte[] { 0, 1 }, 0); apdu1 = iCard.Transmit(apduCmd); if (apdu1.SW1 != 0x90) { System.Threading.Thread.Sleep(100); apdu1 = iCard.Transmit(apduCmd); if (apdu1.SW1 != 0x90) { return(false); } } System.Threading.Thread.Sleep(100); return(true); }
public bool SelectApplication() { APDUCommand apduSelectPxyApl = new APDUCommand(0x00, 0xA4, 4, 0, m_JPNAID, 0); APDUResponse apdu1 = this.cardUpdater.Transmit(apduSelectPxyApl); byte[] apduRespByte = apdu1.Packet; return(checkExchangeApduResult(apduRespByte)); }
private void ReadGPO() { //get processing options APDUCommand apduGPO = new APDUCommand(0x80, 0xa8, 0, 0, new byte[] { 0x83, 0 }, 0); APDUResponse apdu1 = this.cardUpdater.Transmit(apduGPO); if (apdu1.SW1 != 0x90) { throw new Exception("Read GPO Data fail"); } //two possible forms, 0x80 and 0x77 if (apdu1.Data[0] == 0x80) { for (int i = 4; i < apdu1.Data.Length; i += 4) { byte sfi = (byte)((apdu1.Data[i] >> 3) & 0xf); byte lowRange = apdu1.Data[i + 1]; byte hiRange = apdu1.Data[i + 2]; byte[] records = new byte[hiRange - lowRange + 1]; for (int j = lowRange; j <= hiRange; j++) { records[j - lowRange] = (byte)j; } sfiRecords.Add(new SFIRecords(sfi, records)); } } else if (apdu1.Data[0] == 0x77) { //look for the application file locator AFL int a, tag; for (a = 2; (tag = ReadTag(apdu1.Data, a)) != 0x94; a = SkipTag(apdu1.Data, a)) { ; } if (tag == 0x94) { //found it a++; int len = apdu1.Data[a++]; for (int i = a; i < a + len; i += 4) { byte sfi = (byte)((apdu1.Data[i] >> 3) & 0xf); byte lowRange = apdu1.Data[i + 1]; byte hiRange = apdu1.Data[i + 2]; byte[] records = new byte[hiRange - lowRange + 1]; for (int j = lowRange; j <= hiRange; j++) { records[j - lowRange] = (byte)j; } sfiRecords.Add(new SFIRecords(sfi, records)); } } } else { throw new Exception("Unknown GPO template"); } }
public bool SelectApplication() { //select the PSE application APDUCommand apduSelectPSEApl = new APDUCommand(0x00, 0xA4, 4, 0, m_PSEAID, 0); APDUResponse apduPSE = this.cardUpdater.Transmit(apduSelectPSEApl); if (apduPSE.SW1 == 0x90) //PSE supported { //send the Read Record command, record 1, SFI 1 //P2 format: MSB LSB // 7 6 5 4 3 2 1 0 // SFI SFI SFI SFI SFI 1 0 0 //1 0 0 in the LSB bits means that P1 is a record number APDUCommand apduReadRecord = new APDUCommand(0x00, 0xB2, 1, 0xc, null, 0); APDUResponse apdu1 = this.cardUpdater.Transmit(apduReadRecord); if (apdu1.SW1 == 0x90) { m_EMVAID = new byte[apdu1.Data[5]]; Array.Copy(apdu1.Data, 6, m_EMVAID, 0, m_EMVAID.Length); APDUCommand apduSelectEMVApl = new APDUCommand(0x00, 0xA4, 4, 0, m_EMVAID, 0); APDUResponse apdu2 = this.cardUpdater.Transmit(apduSelectEMVApl); if (apdu2.SW1 == 0x90) { //Label = ASCIIEncoding.ASCII.GetString(apdu2.Data, 15, apdu2.Data[14]); if (apdu2.Data[0] == 0x6f) //fci template { ExtractData(ReadTagData(apdu2.Data, 0)); } return(true); } } } //PSE unsupported, need to try AID list foreach (byte[] aid in aidList) { APDUCommand apduSelectEMVApl = new APDUCommand(0x00, 0xA4, 4, 0, aid, 0); APDUResponse apdu2 = this.cardUpdater.Transmit(apduSelectEMVApl); if (apdu2.SW1 == 0x90) { //Label = ASCIIEncoding.ASCII.GetString(apdu2.Data, 15, apdu2.Data[14]); //found it! m_EMVAID = aid; if (apdu2.Data[0] == 0x6f) //fci template { ExtractData(ReadTagData(apdu2.Data, 0)); } return(true); } } return(false); }
private void SetLength(short len) { byte[] paramBytes = new byte[] { 8, 0, 0, 0, 0 }; byte[] lenBytes = BitConverter.GetBytes(len); Array.Copy(lenBytes, 0, paramBytes, 3, 2); APDUCommand setLengthAPdu = new APDUCommand(0xc8, 0x32, 0, 0, paramBytes, 0); APDUResponse apdu1 = this.cardUpdater.Transmit(setLengthAPdu); if (apdu1.SW1 != 0x91 || apdu1.SW2 != 8) { throw new Exception("Failed to read"); } ; }
private byte[] ReadInfo(short len) { MemoryStream ms = new MemoryStream(); while (len > 0) { byte readLen = (byte)(len < 255 ? len : 255); APDUCommand readInfoApdu = new APDUCommand(0xcc, 6, 0, 0, null, readLen); APDUResponse apdu1 = this.cardUpdater.Transmit(readInfoApdu); if (apdu1.SW1 != 0x94 && apdu1.SW1 != 0x90) { throw new Exception("Failed to read"); } ; len -= readLen; ms.Write(apdu1.Data, 0, apdu1.Data.Length); } return(ms.ToArray()); }
private void SelectInfo(short filen1, short filen2, short offset, short len) { byte[] paramBytes = new byte[8]; byte[] n1Bytes = BitConverter.GetBytes(filen1); byte[] n2Bytes = BitConverter.GetBytes(filen2); byte[] offsetBytes = BitConverter.GetBytes(offset); byte[] lenBytes = BitConverter.GetBytes(len); Array.Copy(n2Bytes, 0, paramBytes, 0, 2); Array.Copy(n1Bytes, 0, paramBytes, 2, 2); Array.Copy(offsetBytes, 0, paramBytes, 4, 2); Array.Copy(lenBytes, 0, paramBytes, 6, 2); APDUCommand setLengthAPdu = new APDUCommand(0xcc, 0, 0, 0, paramBytes, 0); APDUResponse apdu1 = this.cardUpdater.Transmit(setLengthAPdu); if (apdu1.SW1 != 0x94) { throw new Exception("Failed to read"); } ; }
private byte[] mifareGetData(byte paramByte1, byte paramByte2, byte paramByte3) { /*int i = 0; * byte[] arrayOfByte1 = new byte[5 + this.m_proxyAppletAID.Length]; * arrayOfByte1[0] = 0; * arrayOfByte1[1] = 0xa4; * arrayOfByte1[2] = 4; * arrayOfByte1[3] = 0; * arrayOfByte1[4] = (byte)this.m_proxyAppletAID.Length; * Array.Copy(this.m_proxyAppletAID, 0, arrayOfByte1, 5, this.m_proxyAppletAID.Length); * byte[] arrayOfByte2 = new byte[5]; * byte[] arrayOfByte3 = null; * int j = 0; * arrayOfByte2[0] = 0x80; * arrayOfByte2[1] = paramByte1; * arrayOfByte2[2] = paramByte2; * arrayOfByte2[3] = paramByte3; * arrayOfByte2[4] = 0;*/ try { byte[] arrayOfByte3; //APDUCommand apduSelectPxyApl = new APDUCommand(0x00, 0xA4, 4, 0, m_proxyAppletAID, 0); //APDUResponse apdu1 = this.cardUpdater.Transmit(apduSelectPxyApl); //arrayOfByte3 = apdu1.Packet; //if (!checkExchangeApduResult(arrayOfByte3)) //return arrayOfByte3; APDUResponse apdu3 = this.cardUpdater.Transmit(new APDUCommand(0x80, paramByte1, paramByte2, paramByte3, null, 1)); arrayOfByte3 = apdu3.Packet; checkExchangeApduResult(arrayOfByte3); return(arrayOfByte3); //j = arrayOfByte3.Length; } catch (Exception localException) { //localException.printStackTrace(); } return(null); }
public void ReadCard() { //read balance 80 32 00 03 04 00 00 00 00 //received: Deposit(BCD) // vvvvv // 05 11 11 25 02 03 12 15 37 20 00 25 09 08 60 00 00 0A 00 18 00 00 00 00 90 00 // ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^ ^^ // CAN issue date months of validity // 2009/08 60 mths APDUCommand apduCmd = new APDUCommand(0x80, 0x32, 0, 3, new byte[4], 0); APDUResponse apdu1 = iCard.Transmit(apduCmd); byte[] balanceBytes = new byte[4]; balanceBytes[0] = apdu1.Data[3]; balanceBytes[1] = apdu1.Data[2]; balanceBytes[2] = apdu1.Data[1]; balanceBytes[3] = apdu1.Data[0]; //balance is in cents. divide by 100 to get dollars Balance = BitConverter.ToInt32(balanceBytes, 0) / 100.0f; //dunno what the heck is this command, probably selecting something apduCmd = new APDUCommand(0, 0xa4, 2, 0, new byte[] { 0, 1 }, 0); apdu1 = iCard.Transmit(apduCmd); //read CAN, expiry date, deposit 00 B0 00 00 18 apduCmd = new APDUCommand(0x00, 0xb0, 0, 0, null, 0x18); apdu1 = iCard.Transmit(apduCmd); //card number (CAN) Number = ConvertBCDCardNumber(apdu1.Data, 1, 8); //get the string form XXXX-XXXX-XXXX-XXXX StringBuilder sb = new StringBuilder(); sb.Append(ConvertBCDCardNumber(apdu1.Data, 1, 2).ToString("D4")); sb.Append("-"); sb.Append(ConvertBCDCardNumber(apdu1.Data, 3, 2).ToString("D4")); sb.Append("-"); sb.Append(ConvertBCDCardNumber(apdu1.Data, 5, 2).ToString("D4")); sb.Append("-"); sb.Append(ConvertBCDCardNumber(apdu1.Data, 7, 2).ToString("D4")); NumberString = sb.ToString(); //read expiry date int year = apdu1.Data[12]; //year, from 1900 or 2000 if (year > 90 && year < 100) { year += 1900; } else { year += 2000; } byte month = apdu1.Data[13]; byte validity = (byte)ConvertBCDCardNumber(apdu1.Data, 14, 1); //validity in months DateTime issueDate = new DateTime(year, month, 1); Expiry = issueDate.AddMonths(validity); ExpiryString = Expiry.ToString("dd MMM yyyy"); Deposit = ConvertBCDCardNumber(apdu1.Data, 15, 2) / 100.0f; //get transaction log //read number of total entries in log apduCmd = new APDUCommand(0, 0xb0, 0, 2, null, 4); apdu1 = iCard.Transmit(apduCmd); if (apdu1.SW1 != 0x90) { throw new Exception("Read NETS log size fail"); } short logSize = (short)ConvertBCDCardNumber(new byte[] { apdu1.Data[2], apdu1.Data[3] }, 0, 2); apduCmd = new APDUCommand(0, 0xa4, 2, 0, new byte[] { 0, 5 }, 0); apdu1 = iCard.Transmit(apduCmd); if (apdu1.SW1 != 0x90) { throw new Exception("Read NETS transaction fail"); } //read the current log entry number short endOffs = (short)(logSize * 4); byte endP1 = (byte)((endOffs >> 8) & 0xff); byte endP2 = (byte)(endOffs & 0xff); apduCmd = new APDUCommand(0, 0xb0, endP1, endP2, null, 2); apdu1 = iCard.Transmit(apduCmd); if (apdu1.SW1 != 0x90) { throw new Exception("Read NETS current log number fail"); } short currentLogNum = (short)ConvertBCDCardNumber(new byte[] { apdu1.Data[0], apdu1.Data[1] }, 0, 2); currentLogNum -= 2; //read each log entry from the ring buffer, starting from current for (byte n = 0; n < logSize; n++) { int i = currentLogNum - n; if (i < 0) { i += logSize; } short logOffs = (short)(i * 4); byte logP1 = (byte)((logOffs >> 8) & 0xff); byte logP2 = (byte)(logOffs & 0xff); //read binary 0xb0, offset logOffs, size 16 apduCmd = new APDUCommand(0, 0xb0, logP1, logP2, null, 16); apdu1 = iCard.Transmit(apduCmd); if (apdu1.SW1 != 0x90) { throw new Exception("Read NETS log entry fail"); } NETSTransaction logEntry = new NETSTransaction(apdu1.Data); if (logEntry.Type != 0) { TransactionLog.Add(logEntry); } } }