public bool TryExtractType1(EMVCard card) { try { var selectedDir = Handler.SelectApplication("1PAY.SYS.DDF01"); if (selectedDir.Tag != 0x6F) { return(false); } var selectedDirInner = selectedDir.ReadInnerTlvTags(); var fciIssuerTag = selectedDirInner.FirstOrDefault(x => x.Tag == 0xA5); if (fciIssuerTag == null) { return(false); } var fciIssuerTagInner = fciIssuerTag.ReadInnerTlvTags(); var sfi = fciIssuerTagInner.FirstOrDefault(x => x.Tag == 0x88); if (sfi == null) { return(false); } byte recordId = 1; ushort sw12 = 0; byte priorityMin = 255; byte[] aidMinPriority = null; do { var readRecordResult = Handler.ReadRecord(sfi.Value[0], recordId, out sw12); ProcessInnerRecord(readRecordResult, ref aidMinPriority, ref priorityMin); recordId++; }while (sw12 == 0x9000); if (aidMinPriority == null) { return(false); } return(ProcessCardFromAID(aidMinPriority, card)); } catch (SL600Sharp.SL600Exception) { return(false); } }
public void Extract(EMVCard card) { if (TryExtractType1(card)) { return; } return; }
static void Main(string[] args) { var factory = SL600Sharp.SL600SDKFactory.CreateFactory( Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "MasterRD.dll")); var resolver = CreateResolver(); using (var sdk = factory.CreateInstance()) using (var reader = new SL600Sharp.SmartCards.Sl600SmartCardReader(sdk, 0) { IsEmv = true }) { var handler = new EMVCardHandler(reader); var extractor = new CardDataExtractor(handler) { PDOLResolver = resolver }; while (true) { if (Console.KeyAvailable) { if (Console.ReadKey().Key == ConsoleKey.Escape) { break; } } else { if (reader.IsCardExist()) { var card = new EMVCard(); extractor.Extract(card); Console.WriteLine($"=========================={card.CardName}=========================="); Console.WriteLine("PAN: {0}\r\nCARDHOLDER: {1}\r\nEXPIRATION: {2}\r\nISSUED: {3}", card.PAN != null ? ByteToHex(card.PAN) : "NULL", card.CardholderName, card.ExpirationDate, card.IssuedDate); Console.WriteLine("======================================================================"); Console.WriteLine(); Thread.Sleep(3000); } Thread.Sleep(500); } } } }
private void ProcessMembank(TLVObject memBank, EMVCard card) { if (memBank.Tag == 0x70 || memBank.Tag == 0x77) { var membankInner = memBank.ReadInnerTlvTags(); foreach (var tag in membankInner) { switch (tag.Tag) { case 0x56: //Handle track 1 data break; case 0x57: //Handle track 2 data break; case 0x58: //Handle track 3 data break; case 0x59: case 0x5F24: //Handle expiration date { var bcdDate = tag.Value; card.ExpirationDate = new DateTime(2000 + (int)FromBCD(bcdDate[0]), (int)FromBCD(bcdDate[1]), (int)FromBCD(bcdDate[2])); } break; case 0x5F25: { var bcdDate = tag.Value; card.IssuedDate = new DateTime(2000 + (int)FromBCD(bcdDate[0]), (int)FromBCD(bcdDate[1]), (int)FromBCD(bcdDate[2])); } break; case 0x5A: card.PAN = tag.Value; break; case 0x5F20: case 0x9F0B: card.CardholderName = Encoding.ASCII.GetString(tag.Value); break; } } } }
private bool ProcessCardFromAID(byte[] aid, EMVCard card) { var selectedApplication = Handler.SelectApplication(aid); if (selectedApplication.Tag != 0x6F) { return(false); } var aidInnerEntries = selectedApplication.ReadInnerTlvTags(); var aidFCI = aidInnerEntries.FirstOrDefault(x => x.Tag == 0xA5); if (aidFCI == null) { return(false); } var aidFCIInner = aidFCI.ReadInnerTlvTags(); var aidNameTag = aidFCIInner.FirstOrDefault(x => x.Tag == 0x50); var aidName = aidNameTag == null ? "Unknown" : Encoding.ASCII.GetString(aidNameTag.Value); card.CardName = aidName; var pdol = aidFCIInner.FirstOrDefault(x => x.Tag == 0x9F38); byte[] PDOLResponse = null; if (pdol == null) { PDOLResponse = new byte[] { 0x83, 0x00 }; } else { if (PDOLResolver == null) { throw new SL600Sharp.SL600Exception("No PDOL resolver availible"); } PDOLResponse = PDOLResolver.Resolve(pdol.Value); } var gpoResponse = Handler.GetProcessingOptions(PDOLResponse); byte[] afl = null; ushort auc = 0; if (gpoResponse.Tag == 0x77) { var gpoResponseInner = gpoResponse.ReadInnerTlvTags(); var aucTag = gpoResponseInner.FirstOrDefault(x => x.Tag == 0x82); var aflTag = gpoResponseInner.FirstOrDefault(x => x.Tag == 0x94); if (aflTag == null || aucTag == null) { throw new SL600Sharp.SL600Exception("No AUC or AFL presented"); } auc = (ushort)((aucTag.Value[0] << 8) | aucTag.Value[0]); afl = aflTag.Value; } else if (gpoResponse.Tag == 0x80) { auc = (ushort)((gpoResponse.Value[0] << 8) | gpoResponse.Value[1]); afl = new byte[gpoResponse.Value.Length - 2]; Array.ConstrainedCopy(gpoResponse.Value, 2, afl, 0, afl.Length); } else { throw new SL600Sharp.SL600Exception($"Not supported tag for GPO operation ({gpoResponse.Tag.Value.ToString("X2")})"); } for (int i = 0; i < afl.Length; i += 4) { var sfiFromAFL = afl[i] >> 3; var firstRec = afl[i + 1]; var lastRec = afl[i + 2]; var sda = afl[i + 3]; for (byte page = firstRec; page <= lastRec; page++) { ProcessMembank(Handler.ReadRecord((byte)sfiFromAFL, page), card); } } return(true); }