public static FCITemplate selectFile(CardChannel channel, String fileID) { String CLASS = "00"; String INSTRUCTION = "A4"; String PARAM1 = "00"; String PARAM2 = "00"; String dataIN = fileID; byte CLASSbyte = Utils.hexStringToByteArray(CLASS)[0]; byte INSbyte = Utils.hexStringToByteArray(INSTRUCTION)[0]; byte P1byte = Utils.hexStringToByteArray(PARAM1)[0]; byte P2byte = Utils.hexStringToByteArray(PARAM2)[0]; //ResponseAPDU r = Utils.sendCommand(channel, CLASSbyte, INSbyte, P1byte, P2byte, Utils.hexStringToByteArray(dataIN), 0); //// Si la lectura del archivo es exitosa debo construir el fci template //if (r.getSW1() == (int)0x90 && r.getSW2() == (int)0x00) //{ // FCITemplate fcit = new FCITemplate(); // fcit.buildFromBuffer(r.getData(), 0, r.getData().length); // return fcit; //} //else //{ // return null; //} return(null); }
public static bool readCertificate(CardChannel channel) { FCITemplate fcit = selectFile(channel, "B001"); certificate_HEX_DER_encoded = readBinary(channel, fcit.getFileSize()); return(true); }
public static String[] datosCedula(CardChannel channel) { String[] resultado = new String[6]; readCertificate(channel); //CertificateFactory cf = CertificateFactory.getInstance("X.509"); //MemoryStream b64eIDCertificate = new MemoryStream(Utils.hexStringToByteArray(certificate_HEX_DER_encoded)); //System.Security.Cryptography.X509Certificates.X509Certificate eIDCertificate = (X509Certificate)cf.generateCertificate(b64eIDCertificate); //String certSerialNumber = Utils.formatHexaString(eIDCertificate.getSerialNumber().toString(16)); //resultado[0] = certSerialNumber; //resultado[1] = eIDCertificate.getIssuerDN() + ""; //resultado[2] = eIDCertificate.getNotBefore() + ""; //resultado[3] = eIDCertificate.getNotAfter() + ""; //resultado[4] = eIDCertificate.getSubjectDN() + ""; FCITemplate fcit7004 = selectFile(channel, "7004"); resultado[5] = readBinary(channel, fcit7004.getFileSize()); return(resultado); }
private void Run() { Console.WriteLine("=========== S o m e T L V D a t a e x a m p l e s"); #region >> TLV Example Console.WriteLine("88 01 02".ToTlvData()); var tlv1 = "88 01 02".ToTlvData(); var tlv2 = "5F 2D 03 01 02 03".ToTlvData(); var ltlv = new List <TlvData>(); ltlv.Add(tlv1); ltlv.Add(tlv2); Console.WriteLine(ltlv.ToTlvData(0x20)); Console.WriteLine(ltlv.ToTlvData(0x20).GetTag(0x88)); Console.WriteLine(ltlv.ToTlvData(0x20).GetTag(0x5F2D)); #endregion Console.WriteLine(); Console.WriteLine("=========== I n i t i a l i z i n g P C / S C"); xmlRoot = new XElement("WinSCard"); xmlDoc = new XDocument(xmlRoot); #region >> ConsoleObserver var logger = new ConsoleObserver(); #endregion #region >> CardContext ICardContext context = new CardContext(); logger.ObserveContext((CardContextObservable)context); if (context.Establish() != ErrorCode.Success) { Console.WriteLine("Erreur: establish() failed"); return; } context.ListReaderGroups(); if (context.GroupsCount == 0) { Console.WriteLine("Error: no reader group found"); context.Release(); return; } context.ListReaders(context.Groups[0]); if (context.ReadersCount == 0) { Console.WriteLine("Error: no reader found"); context.Release(); return; } #endregion Console.WriteLine(); Console.WriteLine("=========== C a r d i n s e r t i o n d e t e c t i o n"); #region >> StatusChangeMonitor var monitor = new StatusChangeMonitor(context); logger.ObserveMonitor(monitor); var readerState = monitor.WaitForCardPresence(0); if (readerState == null) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(">> Insert a card in one of the {0} readers (time out in 15s)", context.ReadersCount); readerState = monitor.WaitForCardPresence(15000); } if (readerState == null) { Console.WriteLine(">> Time Out! No card found"); return; } #endregion #region >> CardChannel ICardChannel rawCardChannel = new CardChannel(context, readerState.ReaderName); logger.ObserveChannel((CardChannelObservable)rawCardChannel); var cardChannel = new CardChannelIso7816(rawCardChannel); if (cardChannel.Connect(ShareMode.Shared, Protocol.Any) != ErrorCode.Success) { Console.WriteLine("Erreur: connect() failed"); return; } var buffer = new byte[0]; cardChannel.GetAttrib(Attrib.AtrString, ref buffer); if (cardChannel.Reconnect(ShareMode.Shared, Protocol.Any, Disposition.ResetCard) != ErrorCode.Success) { Console.WriteLine("Erreur: reconnect() failed"); return; } cardChannel.GetAttrib(Attrib.AtrString, ref buffer); #endregion #region >> TagsManager tagsManager = SerializedObject <TlvDictionary> .LoadFromXml(@"Dictionary.EMVTag.xml"); #endregion #region >> PSE Analysis var pse = new PaymentSystemEnvironment(cardChannel); pse.BeforeSelectEvent += BeforePseSelection; pse.AfterSelectEvent += AfterPseSelection; pse.BeforeReadEvent += BeforePseRead; pse.AfterReadEvent += AfterPseRead; if (pse.Select() == 0x9000) { if (pse.TlvFci.HasTag(0x88)) { pse.Read(); } } #endregion emvApplications = new List <EmvApplication>(); foreach (var emvFound in pse.GetApplications()) { emvApplications.Add(emvFound); } #region >> AID selection foreach (var emv in emvApplications) { emv.BeforeSelectEvent += BeforeApplicationSelection; emv.AfterSelectEvent += AfterApplicationSelection; emv.BeforeGetProcessingOptionsEvent += BeforeGetProcessingOptions; emv.AfterGetProcessingOptionsEvent += AfterGetProcessingOptions; emv.BeforeReadApplicationDataEvent += BeforeReadApplicationData; emv.AfterReadApplicationDataEvent += AfterReadApplicationData; emv.BeforeGetDataEvent += BeforeGetData; emv.AfterGetDataEvent += AfterGetData; if (emv.Select() == 0x9000) { if (emv.GetProcessingOptions() == 0x9000) { emv.ReadApplicationData(); emv.GetData(); } } } #endregion Console.WriteLine(); Console.WriteLine("=========== T e r m i n a t i n g"); cardChannel.Disconnect(Disposition.UnpowerCard); xmlDoc.Save(new FileStream("EMV.TLV.xml", FileMode.Create, FileAccess.ReadWrite)); Console.WriteLine(); Console.WriteLine("=========== C a r d r e m o v a l d e t e c t i o n"); #region >> StatusChangeMonitor Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(">> Waiting for a change since last call (time out in 10s)"); // "unpower" change should be fired for the previously used reader monitor.WaitForChange(10000); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(">> Remove the card in one of the readers {0} (time out in 10s)", readerState.ReaderName); // Wait for another change monitor.WaitForChange(10000); #endregion Console.WriteLine(); context.Release(); }
public static String readBinary(CardChannel channel, int fileSize) { // Construyo el Read Binary, lo que cambia en cada read son P1 y P2 // porque van variando los offset para ir leyendo el binario hasta llegar al tamaño total // en cada read leo FF String CLASS = "00"; String INSTRUCTION = "B0"; String dataIN = ""; String PARAM1; String PARAM2; int FF_int = Int32.Parse("FF", System.Globalization.NumberStyles.HexNumber); int cantBytes = 0; int dataOUTLength = 0; //le String binaryHexString = ""; while (cantBytes < fileSize) { // Calculo el LE // Si la cantidad de Bytes que me quedan por obtener es mayor a // FF entonces me traigo FF. Sino me traigo los Bytes que me quedan. if (cantBytes + FF_int <= fileSize) { dataOUTLength = FF_int; } else { dataOUTLength = fileSize - cantBytes; } // Param1 y param2 comienzan en 00 00, voy incrementando FF bytes hasta leer el total del binario. String PARAM1_PARAM2 = Utils.byteArrayToHex(Utils.intToByteArray(cantBytes)); //uso solo p2 porque la cantidad de bytes que voy leyendo es menor a FF if (cantBytes <= 255) { PARAM1 = "00"; PARAM2 = PARAM1_PARAM2.Substring(0, 2); } else { PARAM1 = PARAM1_PARAM2.Substring(0, 2); PARAM2 = PARAM1_PARAM2.Substring(2, 4); } byte CLASSbyte = Utils.hexStringToByteArray(CLASS)[0]; byte INSbyte = Utils.hexStringToByteArray(INSTRUCTION)[0]; byte P1byte = Utils.hexStringToByteArray(PARAM1)[0]; byte P2byte = Utils.hexStringToByteArray(PARAM2)[0]; //TODO: ResponseAPDU r = Utils.sendCommand(channel, CLASSbyte, INSbyte, P1byte, P2byte, Utils.hexStringToByteArray(dataIN), dataOUTLength); //binaryHexString += Utils.byteArrayToHex(r.getData()); //if (r.getSW1() == (int)0x90 && r.getSW2() == (int)0x00) //{ // cantBytes += dataOUTLength; //} //else //{ // // Fallo algun read binary // return ""; //} } return(binaryHexString); }
private static void Main(/*string[] args*/) { try { Console.WindowWidth = 132; Console.WindowHeight = 50; } catch (Exception) { } Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine(); Console.WriteLine("=========== S t a t u s W o r d D i c t i o n a r y"); #region >> StatusWordDictionary // StatusWordDictionary swd = SerializedObject<StatusWordDictionary>.loadFromXml(@"Dictionary.StatusWord.xml"); // Console.WriteLine("SW: {0:X4} Description: {1}", 0x9000, swd.getDescription(0x90, 0x00)); // Console.WriteLine("SW: {0:X4} Description: {1}", 0x6800, swd.getDescription(0x68, 0x00)); // Console.WriteLine("SW: {0:X4} Description: {1}", 0x6800, swd.getDescription(0x68, 0x84)); // Console.WriteLine("SW: {0:X4} Description: {1}", 0x6A00, swd.getDescription(0x6A, 0x83)); #endregion Console.WriteLine(); Console.WriteLine("=========== C o n s o l e O b s e r v e r"); #region >> ConsoleObserver var logger = new ConsoleObserver(); #endregion Console.WriteLine(); Console.WriteLine("=========== C a r d C o n t e x t"); #region >> CardContext ICardContext context = new CardContext(); logger.ObserveContext((ICardContextObservable)context); context.Establish(); context.ListReaderGroups(); context.ListReaders(context.Groups[0]); #endregion Console.WriteLine(); Console.WriteLine("=========== C a r d i n s e r t i o n d e t e c t i o n"); #region >> StatusChangeMonitor var monitor = new StatusChangeMonitor(context); logger.ObserveMonitor(monitor); var readerState = monitor.WaitForCardPresence(0); if (readerState == null) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(">> Insert a card in one of the {0} readers (time out in 15s)", context.ReadersCount); readerState = monitor.WaitForCardPresence(15000); } if (readerState == null) { Console.WriteLine(">> Time Out! No card found"); return; } #endregion Console.WriteLine(); Console.WriteLine("=========== C a r d C h a n n e l"); #region >> CardChannel ICardChannel cardChannel = new CardChannel(context, readerState.ReaderName); logger.ObserveChannel((ICardChannelObservable)cardChannel); cardChannel.Connect(ShareMode.Shared, Protocol.Any); //Console.WriteLine(cardChannel.getStatus()); byte[] recvBuffer = null; cardChannel.GetAttrib(Attrib.AtrString, ref recvBuffer); recvBuffer = null; cardChannel.GetAttrib(Attrib.DeviceFriendlyName, ref recvBuffer); recvBuffer = null; cardChannel.GetAttrib(Attrib.AtrString, ref recvBuffer); cardChannel.Reconnect(ShareMode.Shared, Protocol.Any, Disposition.ResetCard); Console.WriteLine(); var cAPDU = new CommandAPDU("00A4040005A000000069"); ICardResponse rAPDU = new ResponseAPDU(); cardChannel.Transmit(cAPDU, rAPDU); if (((ResponseAPDU)rAPDU).Sw1 == 0x61) { cAPDU = new CommandAPDU(String.Format("00C00000{0:X2}", ((ResponseAPDU)rAPDU).Sw2)); rAPDU = new ResponseAPDU(); cardChannel.Transmit(cAPDU, rAPDU); } Console.WriteLine(); cAPDU = new CommandAPDU("00A404000E315041592E5359532E4444463031"); rAPDU = new ResponseAPDU(); cardChannel.Transmit(cAPDU, rAPDU); if (((ResponseAPDU)rAPDU).Sw1 == 0x61) { cAPDU = new CommandAPDU(String.Format("00C00000{0:X2}", ((ResponseAPDU)rAPDU).Sw2)); rAPDU = new ResponseAPDU(); cardChannel.Transmit(cAPDU, rAPDU); } cAPDU = new CommandAPDU(0x00, 0xA4, 0x00, 0x00, 0x02, new byte[] { 0x3F, 0x00 }); rAPDU = new ResponseAPDU(); cardChannel.Transmit(cAPDU, rAPDU); if (((ResponseAPDU)rAPDU).Sw1 == 0x61) { cAPDU = new CommandAPDU(String.Format("00C00000{0:X2}", ((ResponseAPDU)rAPDU).Sw2)); rAPDU = new ResponseAPDU(); cardChannel.Transmit(cAPDU, rAPDU); } cardChannel.Disconnect(Disposition.UnpowerCard); #endregion Console.WriteLine(); Console.WriteLine("=========== C a r d C h a n n e l S t a c k"); #region >> CardChannelStack var layers = new List <ICardChannelLayer> { new CardChannelLayer61(), new CardChannelLayer() } .ToObservableLayers() .ForEach(l => logger.ObserveChannel(l)); ICardChannelStack cardStack = new CardChannelStack(layers); cardStack.Attach(context, readerState.ReaderName); cardStack.Connect(ShareMode.Shared, Protocol.Any); cardStack.Reconnect(ShareMode.Shared, Protocol.Any, Disposition.ResetCard); // Use of a CommandResponsePair object to manage the dialog cAPDU = new SelectCommand(SelectCommand.SelectionMode.SelectDFName, SelectCommand.FileOccurrence.FirstOrOnly, SelectCommand.FileControlInformation.ReturnFci, "A000000069".FromHexa(), 0xFF); var crp = new CommandResponsePair(cAPDU); crp.Transmit(cardStack); cardStack.Disconnect(Disposition.UnpowerCard); #endregion Console.WriteLine(); Console.WriteLine("=========== C a r d r e m o v a l d e t e c t i o n"); #region >> StatusChangeMonitor Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(">> Waiting for a change since last call (time out in 10s)"); // "unpower" change should be fired for the previously used reader monitor.WaitForChange(10000); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(">> Remove the card in one of the readers {0} (time out in 10s)", readerState.ReaderName); // Wait for another change monitor.WaitForChange(10000); #endregion Console.WriteLine(); context.Release(); }