Exemple #1
0
        /// <summary>
        /// Obtiene el UID de una tarjeta
        /// </summary>
        /// <param name="card">Tarjeta obtenida</param>
        /// <param name="bAtr">ATR de la tarjeta</param>
        /// <param name="config">Configuración de lectura de la tarjeta</param>
        /// <returns>Devuelve el tipo de retorno de la lectura</returns>
        public bool GetCard(out ICard card, byte[] bAtr, ICardReadConfig config)
        {
            card = null;

            if (bAtr == null)
            {
                bAtr = GetAtr(_hCard, _Name, API.SCARD_PCI_T0 | API.SCARD_PCI_T1);
                if (bAtr == null)
                {
                    return(false);
                }
            }
            if (IsDniE(bAtr))
            {
                // Leer el Contenido del DNIe

                //http://delphi.jmrds.com/node/78
                //https://social.msdn.microsoft.com/Forums/es-ES/044965fe-5a3c-4ec9-8d30-3880cc6d420a/traducir-cdigo-c-as-vbnet?forum=vcses
                //https://social.msdn.microsoft.com/Forums/es-ES/24a95872-8207-499c-b158-167991d00343/lector-de-tarjetas?forum=vbes

                using (MemoryStream ms = new MemoryStream())
                {
                    if (SCardReadFile(_hCard, new byte[] { 0x60, 0x04 }, ms))
                    {
                        Asn1Parser a = new Asn1Parser();
                        a.LoadData(ms);

                        Asn1Node pais = a.GetNodeByPath("/2/0/1/0/0/1");
                        Asn1Node niff = a.GetNodeByPath("/2/0/1/1/0/1");
                        Asn1Node fame = a.GetNodeByPath("/2/0/1/2/0/1");
                        Asn1Node xame = a.GetNodeByPath("/2/0/1/3/0/1");
                        Asn1Node name = a.GetNodeByPath("/2/0/1/4/0/1");

                        string snif   = Encoding.UTF8.GetString(niff.Data);
                        string spais  = Encoding.UTF8.GetString(pais.Data);
                        string ssname = Encoding.UTF8.GetString(xame.Data);
                        string fname  = Encoding.UTF8.GetString(fame.Data);
                        string sname  = Encoding.UTF8.GetString(name.Data).Replace("(AUTENTICACIÓN)", "").Trim();

                        card = new CardDnie(bAtr)
                        {
                            Id = snif, Country = spais, CompleteName = sname, Name = ssname, Surname1 = fname
                        };
                    }
                }

                // Leemos el IDESP con la ruta 0006
                // Leemos la version con la ruta 2F03
                // Leemos el CDF con la ruta 5015 6004
            }
            else
            {
                // Buscar tipo de tarjeta Mifare según el ATR

                CardMifare.EMifareType type = CardMifare.EMifareType.Unknown;
                if (bAtr.Length >= 18)
                {
                    if (bAtr[0] == 0x3B)
                    {
                        // http://downloads.acs.com.hk/drivers/en/API-ACR122U-2.02.pdf

                        // Mifare
                        if (bAtr[13] == 0)
                        {
                            switch (bAtr[14])
                            {
                            case 0x01: type = CardMifare.EMifareType.Classic1K; break;

                            case 0x02: type = CardMifare.EMifareType.Classic4K; break;

                            case 0x03: type = CardMifare.EMifareType.UltraLight; break;

                            case 0x26: type = CardMifare.EMifareType.Mini; break;
                            }
                        }
                    }
                }

                ConfigMifareRead cfg = null;
                if (config != null)
                {
                    if (!(config is ConfigMifareRead))
                    {
                        throw (new ArgumentException("Config must be ConfigMifareRead for Mifare Reads", "config"));
                    }

                    cfg = (ConfigMifareRead)config;
                }

                // Get UID command for Mifare cards
                byte[] receivedUID = SendCmd(_hCard, new byte[] { 0xFF, 0xCA, 0x00, 0x00, 0x00 });
                if (receivedUID == null)
                {
                    return(false);
                }

                card = new CardMifare(type, bAtr)
                {
                    Id = NFCHelper.Buffer2Hex(receivedUID, 0, receivedUID.Length - 2).ToUpperInvariant(),
                };

                if (cfg != null && cfg.RequireReadSomething)
                {
                    CardMifare xcard = (CardMifare)card;

                    // Creamos la tarjeta según su tipo
                    xcard.InitCard();

                    byte[] data;

                    // Establecemos las claves en el lector
                    if (cfg.KeysZero != null)
                    {
                        // Cargar la K0
                        data = SendCmd(_hCard, new byte[] { 0xFF, 0x82, 0x00, 0x00, 0x06, }.Concat(cfg.KeysZero).ToArray());
                        if (data == null || data.Length != 2)
                        {
                            return(false);
                        }
                    }

                    if (cfg.KeysOne != null)
                    {
                        // Cargar la K1
                        data = SendCmd(_hCard, new byte[] { 0xFF, 0x82, 0x00, 0x01, 0x06, }.Concat(cfg.KeysOne).ToArray());
                        if (data == null || data.Length != 2)
                        {
                            return(false);
                        }
                    }

                    // Leer los sectores que se precisan
                    //byte blockNum;
                    ConfigMifareReadSector[] readSectors = cfg.ReadSectors;

                    foreach (CardMifare.Sector sector in xcard.Sectors)
                    {
                        ConfigMifareReadSector readCfg = readSectors[sector.SectorNum];
                        if (readCfg == null || !readCfg.ReadSomething)
                        {
                            continue;
                        }

                        // General Authenticate - Peer sector

                        if (readCfg.Login != null)
                        {
                            // Login al primer sector
                            data = SendCmd(_hCard, new byte[] { 0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, sector.DataBlocks[0].BlockNum,
                                                                (byte)(readCfg.Login.KeyType == ConfigMifareRead.EKeyType.A ? 0x60 : 0x61),
                                                                (byte)(readCfg.Login.KeyNum == ConfigMifareRead.EKeyNum.Zero ? 0x00 : 0x01) });
                        }

                        List <CardMifare.Block> bRead = new List <CardMifare.Block>();

                        if (readCfg.ReadDataBlocks)
                        {
                            for (int x = (int)readCfg.ReadDataBlockStart, m = (int)readCfg.ReadDataBlockEnd; x <= m; x++)
                            {
                                bRead.Add(sector.DataBlocks[x]);
                            }
                        }
                        if (readCfg.ReadTrailBlock)
                        {
                            bRead.Add(sector.TrailingBlock);
                        }

                        //if (data != null && data.Length == 2)
                        foreach (CardMifare.Block block in bRead)
                        {
                            //blockNum = block.BlockNum;// byte.Parse(block.BlockNum.ToString().PadLeft(2, '0'), NumberStyles.HexNumber);

                            //if (cfg.Login != null)
                            //{
                            //    data = SendCmd(_hCard, new byte[] { 0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, block.BlockNum,
                            //       (byte)(cfg.Login.KeyType == ConfigMifareRead.EKeyType.A ? 0x60 : 0x61),
                            //       (byte)(cfg.Login.KeyNum == ConfigMifareRead.EKeyNum.Zero ? 0x00 : 0x01) });

                            //    if (data == null || data.Length != 2) continue;
                            //}

                            // Read Binary
                            data = SendCmd(_hCard, new byte[] { 0xFF, 0xB0, 0x00, block.BlockNum, 0x10 });
                            if (data != null && data.Length == 18)
                            {
                                block.CopyFrom(data);
                            }
                        }
                    }
                }
            }

            // Eliminar ids vacios
            if (card != null && card.Id.Trim('0') == "")
            {
                card = null;
            }

            return(card != null);
        }
        bool InternalRun(bool check)
        {
            byte[] file = System.IO.File.ReadAllBytes(File.FullName);

            using (CardReaderCollection cardReaderCollections = new CardReaderCollection())
                using (CardReader reader = cardReaderCollections[Target.Name])
                {
                    switch (reader.Connect())
                    {
                    case EConnection.Error:
                    {
                        WriteError("Error while connect to " + reader.Name);
                        return(false);
                    }

                    case EConnection.NotCard:
                    {
                        WriteError("Card not present, please insert a card");
                        return(false);
                    }
                    }

                    ICard ic;
                    if (!reader.GetCard(out ic, null))
                    {
                        WriteError("Error while getting card");
                        return(false);
                    }

                    if (ic == null)
                    {
                        WriteError("Please insert a card");
                        return(false);
                    }

                    WriteInfo("Card id ..........", ic.Id.ToString(), ConsoleColor.Cyan);
                    WriteInfo("Card type ........", ic.Type.ToString(), ConsoleColor.Cyan);

                    if (!(ic is CardMifare))
                    {
                        WriteError("Card not is mifare");
                        return(false);
                    }

                    CardMifare card = (CardMifare)ic;
                    WriteInfo("Mifare type ......", card.MifareType.ToString(), ConsoleColor.Cyan);
                    card.InitCard();

                    switch (card.MifareType)
                    {
                    case CardMifare.EMifareType.Classic1K:
                    {
                        int dSec   = card.Sectors[0].DataBlocks[0].Data.Length;
                        int length = card.Sectors.Length * (dSec * 4);       //6 key a / 6 keyb / 4 rights

                        if (file.Length != length)
                        {
                            WriteError("File length must be " + StringHelper.Convert2KbWithBytes(length));
                            return(false);
                        }
                        WriteInfo("Total sectors ....", card.Sectors.Length.ToString(), ConsoleColor.Cyan);

                        length = 0;
                        foreach (CardMifare.Sector sector in card.Sectors)
                        {
                            if (OnlySectors != null && OnlySectors.Count > 0 && !OnlySectors.Contains(sector.SectorNum))
                            {
                                length += dSec * (sector.DataBlocks.Length + 1);
                                WriteInfo("Checking sector " + sector.SectorNum.ToString().PadLeft(2, '0'), "Passed", ConsoleColor.Yellow);
                                continue;
                            }

                            byte[] keyA = new byte[6], keyB = new byte[6];

                            Array.Copy(file, length + (dSec * 3), keyA, 0, 6);
                            Array.Copy(file, length + (dSec * 3) + 10, keyB, 0, 6);

                            ConfigMifareRead cfg = new ConfigMifareRead()
                            {
                                KeysOne = keyA, KeysZero = keyB
                            };

                            ConfigMifareReadSector sec = cfg.ReadSectors[sector.SectorNum];
                            sec.Login = new LoginMifareMethod()
                            {
                                KeyNum  = KeyType == ConfigMifareRead.EKeyType.A ? ConfigMifareRead.EKeyNum.One : ConfigMifareRead.EKeyNum.Zero,
                                KeyType = KeyType
                            };
                            sec.ReadDataBlockEnd   = ConfigMifareReadSector.EBlockRange.DataBlock03;
                            sec.ReadDataBlockStart = ConfigMifareReadSector.EBlockRange.DataBlock01;
                            sec.ReadTrailBlock     = false;

                            ICard c2;
                            if (!reader.GetCard(out c2, cfg))
                            {
                                WriteError("Error reading sector " + sector.SectorNum.ToString() + " Blocks 1-3");
                                return(false);
                            }

                            CardMifare        card2   = (CardMifare)c2;
                            CardMifare.Sector sector2 = card2.Sectors[sector.SectorNum];

                            bool equal = true;
                            foreach (CardMifare.Block block in sector2.DataBlocks)
                            {
                                // Check block
                                bool blockEqual = true;
                                for (int x = 0, m = block.Data.Length; x < m; x++)
                                {
                                    if (block.Data[x] != file[x + length])
                                    {
                                        blockEqual = false; break;
                                    }
                                }

                                if (!blockEqual)
                                {
                                    equal = false;
                                    if (!check)
                                    {
                                        // Write block
                                        byte[] data = new byte[block.Data.Length];
                                        Array.Copy(file, length, data, 0, data.Length);
                                        if (!block.WriteInBlock(reader, cfg, data))
                                        {
                                            WriteError("Error writting sector " + sector2.SectorNum.ToString() + " block " + block.BlockNum.ToString());
                                        }
                                    }
                                }
                                length += block.Data.Length;
                            }

                            // Info
                            if (!equal)
                            {
                                WriteInfo("Checking sector " + sector.SectorNum.ToString().PadLeft(2, '0'), check ? "Different" : "Modified", ConsoleColor.Red);
                            }
                            else
                            {
                                WriteInfo("Checking sector " + sector.SectorNum.ToString().PadLeft(2, '0'), "Equal", ConsoleColor.Green);
                            }

                            length += dSec;       //6 key a / 6 keyb / 4 rights
                        }

                        return(true);
                    }

                    default:
                    {
                        WriteError("Card " + card.MifareType.ToString() + " not implemented");
                        return(false);
                    }
                    }
                }
        }