Exemplo n.º 1
0
        public async Task <bool> WriteDataAsync(string readerName, ICollection <MifareKey> keys, byte[] bytesToWrite, CancellationToken ct)
        {
            if (string.IsNullOrEmpty(readerName))
            {
                throw new Exception("readerName is null");
            }
            var contextFactory = ContextFactory.Instance;
            var cardStatus     = await WaitForCardInsert(readerName, contextFactory, ct);

            if (!IsValidATR(cardStatus.Atr))
            {
                throw new Exception("Invalid card type");
            }
            var context = contextFactory.Establish(SCardScope.System);

            using (var isoReader = new IsoReader(context, readerName, SCardShareMode.Shared, SCardProtocol.Any, false))
            {
                var card = new MifareCard(isoReader);
                var loadKeySuccessful = card.LoadKey(
                    KeyStructure.NonVolatileMemory,
                    0x00,            // first key slot
                    keys.First().Key // key
                    );

                if (!loadKeySuccessful)
                {
                    throw new Exception("LOAD KEY failed.");
                }

                if (bytesToWrite.Length > MaxDataSize)
                {
                    throw new Exception($"Data length is more than {MaxDataSize}");
                }

                var generator = GenerateChunk(bytesToWrite).GetEnumerator();
                //write to every block except 0 sector and trailers
                for (byte sectorNumber = 1; sectorNumber < MaxSector; sectorNumber++)
                {
                    for (byte blockNumber = 0; blockNumber < BlocksPerSector - 1; blockNumber++)
                    {
                        var currentBlock = (byte)(sectorNumber * BlocksPerSector + blockNumber);
                        if (CheckIfTrailerBlock(currentBlock))
                        {
                            throw new Exception("Trying to write to trailer block");
                        }

                        byte[] blockToWrite = GetNextBlock(generator);
                        if (blockToWrite == null)
                        {
                            return(true);
                        }

                        //auth in every block
                        var authSuccessful = card.Authenticate(0, currentBlock, KeyType.KeyA, 0x00);
                        if (!authSuccessful)
                        {
                            throw new Exception("AUTHENTICATE failed.");
                        }
                        Debug.WriteLine($"Authentification to block {currentBlock} succeded");


                        Debug.WriteLine($"In block {currentBlock} writing {BitConverter.ToString(blockToWrite)}");
                        var updateResult = card.UpdateBinary(0, currentBlock, blockToWrite);
                        if (updateResult == false)
                        {
                            //fail to write block
                            Debug.WriteLine($"Fail to write block {currentBlock}");
                            return(false);
                        }
                    }
                }
                return(false);
            }
        }
Exemplo n.º 2
0
        private void OnCardInserted(object sender, CardStatusEventArgs e)
        {
            if (!IsValidATR(e.Atr))
            {
                Debug.WriteLine("Card with invalid ATR inserted");
                return;
            }
            Debug.WriteLine("Card with valid ATR inserted");
            var currentContext = ContextFactory.Instance.Establish(SCardScope.System);

            using (var isoReader = new IsoReader(currentContext, e.ReaderName, SCardShareMode.Shared, SCardProtocol.Any))
            {
                var card = new MifareCard(isoReader);
                var loadKeySuccessful = card.LoadKey(
                    KeyStructure.NonVolatileMemory,
                    0x00,                   // first key slot
                    _config.AuthKeys[0].Key // key
                    );

                if (!loadKeySuccessful)
                {
                    //key load failed
                    Debug.WriteLine("Auth key load failed");
                    return;
                }
                Debug.WriteLine("Auth key load success");

                var cardDump = new List <byte>();

                //read all blocks except 0 sector and trailers
                for (byte sectorNumber = 1; sectorNumber < MaxSector; sectorNumber++)
                {
                    for (byte blockNumber = 0; blockNumber < 3; blockNumber++)
                    {
                        var currentBlock = (byte)(sectorNumber * BlocksPerSector + blockNumber);
                        //auth in every block
                        var authSuccessful = card.Authenticate(0, currentBlock, KeyType.KeyA, 0x00);
                        if (!authSuccessful)
                        {
                            //autentication failed
                            Debug.WriteLine($"Authentification to block {currentBlock} with key number {0} failed");
                            return;
                        }
                        Debug.WriteLine($"Authentification to block {currentBlock} succeded");

                        var blockResult = card.ReadBinary(0, currentBlock, BytesPerBlock);
                        if (blockResult == null)
                        {
                            //fail to get block
                            Debug.WriteLine($"Fail to get block {currentBlock}");
                            return;
                        }
                        cardDump.AddRange(blockResult);
                    }
                }

                var result = cardDump.ToArray();
                Debug.WriteLine("Reading complete.");
                if (result.Length != 0)
                {
                    CardRegistered?.Invoke(this, new CardRegisteredEventArgs(result));
                }
            }
        }