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); } }
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)); } } }