From b52a976098bfc72180d3c88c69919d21690ccb39 Mon Sep 17 00:00:00 2001 From: TheJoKlLa Date: Fri, 9 Oct 2020 10:48:07 +0200 Subject: [PATCH] Added: Change Other Key --- NFC/NXP MIFARE DESFire/MIFARE_DESFire_V2.cs | 73 ++++++++++++++++++++- NFC_Test/AES_Test.cs | 26 ++++++++ NFC_Test/MIFARE_DESFire_V2_Test.cs | 27 ++++++++ NFC_Test/OTA.cs | 52 +++------------ 4 files changed, 134 insertions(+), 44 deletions(-) create mode 100644 NFC_Test/AES_Test.cs diff --git a/NFC/NXP MIFARE DESFire/MIFARE_DESFire_V2.cs b/NFC/NXP MIFARE DESFire/MIFARE_DESFire_V2.cs index df5fbe2..dbb7a2c 100644 --- a/NFC/NXP MIFARE DESFire/MIFARE_DESFire_V2.cs +++ b/NFC/NXP MIFARE DESFire/MIFARE_DESFire_V2.cs @@ -70,7 +70,7 @@ namespace NFC.Mifare_DESFire /// Data public string ConvertToHexString(byte[] data) { - return BitConverter.ToString(data).Replace("-", " "); + return BitConverter.ToString(data).Replace("-", "").ToLower(); } /// @@ -679,6 +679,12 @@ namespace NFC.Mifare_DESFire _Log.Debug("End AuthenticateISO_DES"); } + /// + /// Change Same AES key as Authenticated + /// + /// + /// + /// public void ChangeKey_AES(byte key_id, byte[] new_key, byte key_version) { _Log.Debug("Start ChangeKey_AES"); @@ -708,6 +714,9 @@ namespace NFC.Mifare_DESFire byte[] cryptogram_enc = aes.Encrypt(cryptogram_block, _SessionKey, _IV); _Log.DebugFormat("cryptogram_enc: {0}", ConvertToHexString(cryptogram_enc)); + _IV = ExtractLastBlock(cryptogram_enc, 16); + _Log.DebugFormat("_IV: {0}", ConvertToHexString(_IV)); + byte[] data = Concatenate(new byte[] { key_id }, cryptogram_enc); _Log.DebugFormat("data: {0}", ConvertToHexString(data)); @@ -726,6 +735,68 @@ namespace NFC.Mifare_DESFire _Log.Debug("End ChangeKey_AES"); } + + /// + /// Change other AES key as Authenticated + /// + /// + /// + /// + public void ChangeOtherKey_AES(byte key_id, byte[] new_key, byte[] old_key, byte key_version) + { + _Log.Debug("Start ChangeOtherKey_AES"); + + byte[] header = new byte[] + { + 0xC4, key_id + }; + _Log.DebugFormat("header: {0}", ConvertToHexString(header)); + + byte[] key_xor = XOR(new_key, old_key); + + // AES Key Version is Append to Key + byte[] key_and_version = Concatenate(key_xor, new byte[] { key_version }); + byte[] command = Concatenate(header, key_and_version); + _Log.DebugFormat("command: {0}", ConvertToHexString(command)); + + CRC32 crc32 = new CRC32(); + byte[] crc_cmd = crc32.Calculate(command); + _Log.DebugFormat("crc_cmd: {0}", ConvertToHexString(crc_cmd)); + byte[] crc_key = crc32.Calculate(new_key); + _Log.DebugFormat("crc_key: {0}", ConvertToHexString(crc_key)); + + byte[] cryptogram = Concatenate(key_and_version, crc_cmd); + cryptogram = Concatenate(cryptogram, crc_key); + _Log.DebugFormat("cryptogram: {0}", ConvertToHexString(cryptogram)); + + byte[] cryptogram_block = ExpandToBlockSize(cryptogram, 16); + _Log.DebugFormat("cryptogram_block: {0}", ConvertToHexString(cryptogram_block)); + + AES aes = new AES(); + byte[] cryptogram_enc = aes.Encrypt(cryptogram_block, _SessionKey, _IV); + _Log.DebugFormat("cryptogram_enc: {0}", ConvertToHexString(cryptogram_enc)); + + _IV = ExtractLastBlock(cryptogram_enc, 16); + _Log.DebugFormat("_IV: {0}", ConvertToHexString(_IV)); + + byte[] data = Concatenate(new byte[] { key_id }, cryptogram_enc); + _Log.DebugFormat("data: {0}", ConvertToHexString(data)); + + APDUCommand cmd_ChangeKey = new APDUCommand(IsoCase.Case4Short) + { + CLA = 0x90, + INS = 0xC4, + Data = data + }; + _Log.DebugFormat("APDU_CMD(cmd_ChangeKey): {0}", ConvertToHexString(cmd_ChangeKey.ToArray())); + + APDUResponse response = _Card.Transmit(cmd_ChangeKey); + _Log.DebugFormat("APDU_RES(cmd_ChangeKey): {0}", ConvertToHexString(response.ToArray())); + + CheckAPDUResponse(response); + + _Log.Debug("End ChangeOtherKey_AES"); + } #endregion #region Configuration Generator diff --git a/NFC_Test/AES_Test.cs b/NFC_Test/AES_Test.cs new file mode 100644 index 0000000..b35fee2 --- /dev/null +++ b/NFC_Test/AES_Test.cs @@ -0,0 +1,26 @@ +using NFC.Crypto; +using NFC.Mifare_DESFire; +using NUnit.Framework; + +namespace NFC_Test +{ + [TestFixture] + public class AES_Test + { + [Test] + public void Encrypt() + { + MIFARE_DESFire_V2 desfire = new MIFARE_DESFire_V2(null); + + byte[] data = desfire.ConvertFromHexString("8db1f942f2d7cc82f6fa1486a30f8c12104a3b07e8eb77a7ac00000000000000"); + byte[] key = desfire.ConvertFromHexString("e7aff3361c3e85347993c3219a87d24b"); + byte[] iv = desfire.ConvertFromHexString("00000000000000000000000000000000"); + + AES aes = new AES(); + byte[] data_enc = aes.Encrypt(data, key, iv); + + byte[] data_enc_expected = desfire.ConvertFromHexString("3c79d74a4969ba7123e5d8f6df24493112d221fd131a4617d0eda5d92ccc1b46"); + Assert.AreEqual(data_enc_expected, data_enc); + } + } +} \ No newline at end of file diff --git a/NFC_Test/MIFARE_DESFire_V2_Test.cs b/NFC_Test/MIFARE_DESFire_V2_Test.cs index 2b7a7c2..a3a8a2b 100644 --- a/NFC_Test/MIFARE_DESFire_V2_Test.cs +++ b/NFC_Test/MIFARE_DESFire_V2_Test.cs @@ -629,6 +629,33 @@ namespace NFC_Test desfire.ChangeKey_AES(0x00, new_key, 0x10); } + + [Test] + public void ChangeOtherKey_AES() + { + ICard card = Substitute.For(); + + MIFARE_DESFire_V2 desfire = new MIFARE_DESFire_V2(card); + + APDUResponse response = new APDUResponse() + { + SW1 = 0x91, + SW2 = 0x00 + }; + + byte[] new_key = desfire.ConvertFromHexString("8db1f942f2d7cc82f6fa1486a30f8c12"); + byte[] old_key = desfire.ConvertFromHexString("00000000000000000000000000000000"); + + byte[] sessionkey = desfire.ConvertFromHexString("e7aff3361c3e85347993c3219a87d24b"); + byte[] iv = desfire.ConvertFromHexString("00000000000000000000000000000000"); + + desfire._SessionKey = sessionkey; + desfire._IV = iv; + + card.Transmit(null).ReturnsForAnyArgs(response); + + desfire.ChangeOtherKey_AES(0x01, new_key, old_key, 0x10); + } #endregion } } diff --git a/NFC_Test/OTA.cs b/NFC_Test/OTA.cs index b5eb63f..217efa4 100644 --- a/NFC_Test/OTA.cs +++ b/NFC_Test/OTA.cs @@ -1,15 +1,8 @@ using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Text; using NFC; using NFC.Readers.PCSC; -using System.Threading; using NFC.Mifare_DESFire; using NFC.Mifare_DESFire.Enums; -using NFC.ISO7816_4; -using PCSC.Iso7816; -using log4net.Config; namespace NFC_Test { @@ -32,6 +25,7 @@ namespace NFC_Test MIFARE_DESFire_V2 desfire = new MIFARE_DESFire_V2(card); + desfire.SelectApplication(0x000000); desfire.AuthenticateISO_DES(0x00, desfire.GenerateEmptyKey(16)); desfire.Format(); @@ -44,44 +38,16 @@ namespace NFC_Test desfire.SelectApplication(0xC0FFEE); desfire.AuthenticateISO_AES(0x00, desfire.GenerateEmptyKey(16)); - byte[] new_key = desfire.ConvertFromHexString("45eeb8338ae8f49a032e85bb11143530"); + byte[] key_master = desfire.ConvertFromHexString("45eeb8338ae8f49a032e85bb11143530"); + byte[] key_1 = desfire.ConvertFromHexString("8db1f942f2d7cc82f6fa1486a30f8c12"); + byte[] key_2 = desfire.ConvertFromHexString("77611d170c449df6f294c48581ab315d"); + desfire.ChangeKey_AES(0x00, key_master, 0x10); - desfire.ChangeKey_AES(0x00, new_key, 0x10); + desfire.AuthenticateISO_AES(0x00, key_master); + desfire.ChangeOtherKey_AES(0x01, key_1, desfire.GenerateEmptyKey(16), 0x10); - transmit_successfully = true; - - card.Disconnect(); - }; - - reader.CardDiscovered += handler; - reader.Start(); - - Assert.AreEqual(true, transmit_successfully); - - reader.Stop(); - reader.CardDiscovered -= handler; - } - - [Test] - public void ChangeKey() - { - IHardware hardware = new Hardware(); - IReader reader = hardware.OpenReader(_ReaderID); - - bool transmit_successfully = false; - - ReaderEventHandler handler = (sender, card) => - { - card.Connect(); - - MIFARE_DESFire_V2 desfire = new MIFARE_DESFire_V2(card); - - desfire.SelectApplication(0xC0FFEE); - desfire.AuthenticateISO_AES(0x00, desfire.GenerateEmptyKey(16)); - - byte[] new_key = desfire.ConvertFromHexString("45eeb8338ae8f49a032e85bb11143530"); - - desfire.ChangeKey_AES(0x00, new_key, 0x10); + desfire.AuthenticateISO_AES(0x00, key_master); + desfire.ChangeOtherKey_AES(0x02, key_2, desfire.GenerateEmptyKey(16), 0x10); transmit_successfully = true;