示例#1
0
        bool AuthBlock(IsoCard card, int block, bool isAKey = true)
        {
            byte type = 0x60;

            if (!isAKey)
            {
                type = 0x61;
            }

            CommandApdu apdu = card.ConstructCommandApdu(IsoCase.Case3Short);

            apdu.CLA  = 0xFF;
            apdu.INS  = 0x86;
            apdu.P1   = 0x00;
            apdu.P2   = 0x00;
            apdu.Data = new byte[] { 0x01, //version
                                     0x00,
                                     (byte)block,
                                     type,   //Key type 0x60 TYPE_A, 0x61 TYPE_B
                                     0x00 }; //Key number 0x00 ~ 0x1F

            Response response = card.Transmit(apdu);

            if (response.SW1 == (byte)SW1Code.Normal)
            {
                return(true);
            }

            return(false);
        }
示例#2
0
        void UpdateMoney(IsoCard card)
        {
            string cfg   = CardDumper.GetConfigurationKey("UpdateMoney");
            int    money = 0;

            if (!int.TryParse(cfg, out money))
            {
                return;
            }

            string data = DumpMoney(card);

            if (string.IsNullOrEmpty(data))
            {
                return;
            }

            int first  = money & 0x0000FF;
            int second = (money >> 8) & 0x0000FF;

            //9
            // 10

            byte[] bytes = FromHex(data);
            bytes[9]  = (byte)second;
            bytes[10] = (byte)first;

            if (!Write(card, 45, bytes))
            {
                Log("Write failed!");
            }

            DumpMoney(card);
        }
示例#3
0
        void DumpCard(IsoCard card)
        {
            string uid = ReadUID(card);

            Log("UID: " + uid);

            Log("[----------Start of Memory Dump----------]");

            int blockSize = 4;

            for (int sector = 0; sector != 16; ++sector)
            {
                Log("----------------Sector " + string.Format("{0:D2}", sector) + "-----------------");

                for (int block = 0; block != blockSize; ++block)
                {
                    int cardBlock = sector * blockSize + block;

                    string data = Read(card, cardBlock);

                    Log("Block " + string.Format("{0:D2}", cardBlock) + ": " + data);
                }
            }
            Log("[-----------End of Memory Dump-----------]");
        }
示例#4
0
 public IsoCard TryConnect(String cardName)
 {
     try
     {
         IsoCard card = new IsoCard(this.reader);
         card.Connect(cardName, SCardShareMode.Shared, SCardProtocol.Any);
         return(card);
     }
     catch (PCSCException)
     {
         return(null);
     }
 }
示例#5
0
        public List <String> GetConnected()
        {
            List <String> ret     = new List <String>();
            List <String> readers = new List <string>(ctx.GetReaders());

            foreach (string s in readers)
            {
                IsoCard f = TryConnect(s);
                if (f == null)
                {
                    continue;
                }
                ret.Add(s);
            }
            return(ret);
        }
示例#6
0
        string DumpMoney(IsoCard card)
        {
            string uid  = ReadUID(card);
            string data = Read(card, 45);

            if (string.IsNullOrEmpty(data))
            {
                return("");
            }

            string money = data.Substring(18, 4);

            byte[] binary = FromHex(money);
            int    value  = (((int)binary[0]) << 8) | ((int)binary[1]);

            Log("UID: " + uid + " " + value + " cents");

            return(data);
        }
示例#7
0
        bool WriteBlock(IsoCard card, int block, byte[] data)
        {
            CommandApdu apdu = card.ConstructCommandApdu(IsoCase.Case3Short);

            apdu.CLA         = 0xFF;
            apdu.Instruction = InstructionCode.UpdateBinary;
            apdu.P1          = 0x00;
            apdu.P2          = (byte)block;
            apdu.Data        = data;

            Response response = card.Transmit(apdu);

            if (response.SW1 == (byte)SW1Code.Normal)
            {
                return(true);
            }

            return(false);
        }
示例#8
0
        bool LoadKey(IsoCard card, byte[] key)
        {
            CommandApdu apdu = card.ConstructCommandApdu(IsoCase.Case3Short);

            apdu.CLA         = 0xFF;
            apdu.Instruction = InstructionCode.ExternalAuthenticate;
            apdu.P1          = 0x20;
            apdu.P2          = 0x00;
            apdu.Data        = key;

            Response response = card.Transmit(apdu);

            if (response.SW1 == (byte)SW1Code.Normal)
            {
                return(true);
            }

            return(false);
        }
示例#9
0
        void CardInserted(object sender, CardStatusEventArgs args)
        {
            SCardMonitor monitor = (SCardMonitor)sender;

            Log("CardInserted Event for reader: " + args.ReaderName);

            try
            {
                SCardReader reader = new SCardReader(m_card_context);

                if (reader.Connect(args.ReaderName, SCardShareMode.Shared, SCardProtocol.Any) == SCardError.Success)
                {
                    DumpStatus(reader);
                    IsoCard card = new IsoCard(reader);

                    if (CardDumper.IsKeyEnabled("DumpCard"))
                    {
                        DumpCard(card);
                    }

                    if (CardDumper.IsKeyEnabled("DumpMoney"))
                    {
                        DumpMoney(card);
                    }

                    if (!string.IsNullOrEmpty(CardDumper.GetConfigurationKey("UpdateMoney")))
                    {
                        UpdateMoney(card);
                    }
                }

                reader.Disconnect(SCardReaderDisposition.Reset);
            }
            catch (Exception ex)
            {
                Log("Exception: " + ex.ToString());
            }
        }
示例#10
0
        bool Write(IsoCard card, int block, byte[] data)
        {
            bool ok = false;

            byte[] key = null;
            if (m_keys.TryGetValue("A" + block, out key))
            {
                if (LoadKey(card, key) && AuthBlock(card, block, true))
                {
                    ok = WriteBlock(card, block, data);
                }
            }

            if (!ok && m_keys.TryGetValue("B" + block, out key))
            {
                if (LoadKey(card, key) && AuthBlock(card, block, false))
                {
                    ok = WriteBlock(card, block, data);
                }
            }

            return(ok);
        }
示例#11
0
        string ReadUID(IsoCard card)
        {
            string ouput = "";

            CommandApdu apdu = card.ConstructCommandApdu(IsoCase.Case2Short);

            apdu.CLA         = 0xFF;
            apdu.Instruction = InstructionCode.GetData;
            apdu.P1          = 0x00;
            apdu.P2          = 0x00;
            apdu.Le          = 0x00;

            Response response = card.Transmit(apdu);

            if (response.SW1 == (byte)SW1Code.Normal)
            {
                byte[] data = response.GetData();
                if (data != null)
                {
                    ouput = ToHex(data);
                }
            }
            return(ouput);
        }
示例#12
0
        string Read(IsoCard card, int block)
        {
            string ouput = "";

            bool ok = false;

            byte[] key = null;
            if (m_keys.TryGetValue("A" + block, out key))
            {
                if (LoadKey(card, key))
                {
                    if (AuthBlock(card, block, true))
                    {
                        ouput = ReadBlock(card, block);
                        ok    = !string.IsNullOrEmpty(ouput);
                    }
                }
            }

            if (!ok && m_keys.TryGetValue("B" + block, out key))
            {
                // Log("--" + ToHex(key));

                if (LoadKey(card, key))
                {
                    if (AuthBlock(card, block, false))
                    {
                        ouput = ReadBlock(card, block);
                        ok    = !string.IsNullOrEmpty(ouput);
                    }
                }
            }


            return(ouput);
        }
示例#13
0
        static void Main(string[] args)
        {
            // Establish PC/SC context
            SCardContext ctx = new SCardContext();

            ctx.Establish(SCardScope.System);

            // Create a reader object
            SCardReader reader = new SCardReader(ctx);

            // Use the first reader that is found
            string firstreader = ctx.GetReaders()[0];

            // Connect to the card
            IsoCard card = new IsoCard(reader);

            card.Connect(firstreader, SCardShareMode.Shared, SCardProtocol.Any);

            // Build a ATR fetch case
            CommandApdu apdu = card.ConstructCommandApdu(
                IsoCase.Case2Short);

            apdu.CLA = 0x00; // Class
            apdu.INS = 0x84; // Instruction: GET CHALLENGE
            apdu.P1  = 0x00; // Parameter 1
            apdu.P2  = 0x00; // Parameter 2
            apdu.Le  = 0x08; // Expected length of the returned data

            // Transmit the Command APDU to the card and receive the response
            Response resp = card.Transmit(apdu);

            // Show SW1SW2 from the last response packet (if more than one has been received).
            Console.WriteLine("SW1: {0:X2} SW2: {1:X2}", resp.SW1, resp.SW2);

            byte[] data;

            // First test - get the data from all response APDUs
            data = resp.GetData();
            if (data != null)
            {
                Console.Write("CHALLENGE:");

                foreach (byte b in data)
                {
                    Console.Write(" {0:X2}", b);
                }
                Console.WriteLine();
            }

            // Second test - get the data from each response APDU.
            int i = 0;

            foreach (ResponseApdu respApdu in resp.ResponseApduList)
            {
                data = respApdu.GetData();

                if (data != null)
                {
                    Console.Write("APDU ({0}), DATA:", i);
                    foreach (byte b in data)
                    {
                        Console.Write(" {0:X2}", b);
                    }
                    Console.WriteLine();
                    i++;
                }
            }
            return;
        }