mirror of
https://gitlab.com/fabinfra/fabaccess/borepin.git
synced 2025-04-20 02:16:30 +02:00
BackUp
This commit is contained in:
parent
d601e9afb3
commit
f5dffcec5b
@ -3,6 +3,7 @@ using System.Threading;
|
||||
using CoreNFC;
|
||||
using Foundation;
|
||||
using NFC;
|
||||
using NFC.ISO7816_4;
|
||||
|
||||
namespace Borepin.iOS.CNFC
|
||||
{
|
||||
|
44
NFC/Crypto/CRC32.cs
Normal file
44
NFC/Crypto/CRC32.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System;
|
||||
|
||||
namespace NFC.Crypto
|
||||
{
|
||||
public class CRC32
|
||||
{
|
||||
public byte[] Calculate(byte[] data)
|
||||
{
|
||||
UInt32 crc32 = 0xFFFFFFFF;
|
||||
|
||||
crc32 = Calculate(data, crc32);
|
||||
|
||||
return BitConverter.GetBytes(crc32);
|
||||
}
|
||||
|
||||
public byte[] Calculate(byte[] cmd, byte[] data)
|
||||
{
|
||||
UInt32 crc32 = 0xFFFFFFFF;
|
||||
|
||||
crc32 = Calculate(cmd, crc32);
|
||||
crc32 = Calculate(data, crc32);
|
||||
|
||||
return BitConverter.GetBytes(crc32);
|
||||
}
|
||||
|
||||
public UInt32 Calculate(byte[] data, UInt32 crc32)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
crc32 ^= data[i];
|
||||
for (int b = 0; b < 8; b++)
|
||||
{
|
||||
bool b_Bit = (crc32 & 0x01) > 0;
|
||||
crc32 >>= 1;
|
||||
if (b_Bit)
|
||||
{
|
||||
crc32 ^= 0xEDB88320;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc32;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +1,13 @@
|
||||
using NFC.Crypto;
|
||||
using NFC.ISO7816_4;
|
||||
using NFC.Mifare_DESFire.Enums;
|
||||
using Org.BouncyCastle.Asn1.Crmf;
|
||||
using PCSC.Iso7816;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
|
||||
namespace NFC.Mifare_DESFire
|
||||
{
|
||||
|
||||
public class MIFARE_DESFire
|
||||
{
|
||||
// Docs https://hackmd.io/qATu8uYdRnOC40aFrB9afg
|
||||
@ -31,6 +28,9 @@ namespace NFC.Mifare_DESFire
|
||||
/// ICard Implementation used to transmit APDUCommands and recive APDUResponses
|
||||
/// </summary>
|
||||
private ICard _Card;
|
||||
|
||||
public byte[] _SessionKey;
|
||||
public byte[] _IV;
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
@ -43,7 +43,7 @@ namespace NFC.Mifare_DESFire
|
||||
byte[] key = new byte[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
key.[i] = 0;
|
||||
key[i] = 0;
|
||||
}
|
||||
|
||||
return key;
|
||||
@ -64,6 +64,63 @@ namespace NFC.Mifare_DESFire
|
||||
|
||||
}
|
||||
|
||||
public bool CheckKey(byte[] key)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetKeyTypeDES(key);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Key Types used for DESFire Cards
|
||||
/// </summary>
|
||||
public enum KeyType
|
||||
{
|
||||
/// <summary>
|
||||
/// DES Key - 8 Byte - 64 Bit
|
||||
/// </summary>
|
||||
DES,
|
||||
|
||||
/// <summary>
|
||||
/// Triple DES Key with two DES Keys - 16 Byte - 128 Bit
|
||||
/// </summary>
|
||||
TDES_2K,
|
||||
|
||||
/// <summary>
|
||||
/// Triple DES Key with three DES Keys - 24 Byte - 192 Bit
|
||||
/// </summary>
|
||||
TDES_3K,
|
||||
|
||||
/// <summary>
|
||||
/// AES Key - 16 Byte - 128 Bit
|
||||
/// </summary>
|
||||
AES
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check the Key Length to get Type of DES/3DES Key
|
||||
/// </summary>
|
||||
public KeyType GetKeyTypeDES(byte[] key)
|
||||
{
|
||||
switch(key.Length)
|
||||
{
|
||||
case 8:
|
||||
return KeyType.DES;
|
||||
case 16:
|
||||
return KeyType.TDES_2K;
|
||||
case 24:
|
||||
return KeyType.TDES_3K;
|
||||
default:
|
||||
throw new ArgumentException(string.Format("No valid DES/3DES Key Size({0})", key.Length));
|
||||
}
|
||||
}
|
||||
|
||||
#region Methods for Crypto Operation
|
||||
/// <summary>
|
||||
/// Return a copy of the last Block of data
|
||||
@ -141,6 +198,23 @@ namespace NFC.Mifare_DESFire
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public byte[] xor(byte[] a, byte[] b)
|
||||
{
|
||||
if(a.Length != b.Length)
|
||||
{
|
||||
throw new ArgumentException("Array are not same Length");
|
||||
}
|
||||
|
||||
byte[] c = new byte[a.Length];
|
||||
|
||||
for(int i = 0; i < a.Length; i++)
|
||||
{
|
||||
c[i] = (byte)(a[i] ^ b[i]);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
@ -192,7 +266,7 @@ namespace NFC.Mifare_DESFire
|
||||
{
|
||||
byte[] id_byte = BitConverter.GetBytes(aid);
|
||||
|
||||
APDUCommand cmd = new APDUCommand(IsoCase.Case3Short)
|
||||
APDUCommand cmd = new APDUCommand(IsoCase.Case4Short)
|
||||
{
|
||||
CLA = 0x90,
|
||||
INS = (byte)APDUInstructions.SELECT_APPLICATION,
|
||||
@ -201,8 +275,7 @@ namespace NFC.Mifare_DESFire
|
||||
id_byte[0],
|
||||
id_byte[1],
|
||||
id_byte[2]
|
||||
},
|
||||
Le = 0x00
|
||||
}
|
||||
};
|
||||
|
||||
APDUResponse response = _Card.Transmit(cmd);
|
||||
@ -211,7 +284,76 @@ namespace NFC.Mifare_DESFire
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Expand Array to Block Size
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public byte[] expandToBlockSize(byte[] data, int bocksize)
|
||||
{
|
||||
int diff = data.Length % bocksize;
|
||||
if (diff == 0)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
byte[] expand = new byte[data.Length + diff];
|
||||
|
||||
data.CopyTo(expand, 0);
|
||||
|
||||
for(int i = expand.Length - 1; i > data.Length - 1; i--)
|
||||
{
|
||||
expand[i] = 0x00;
|
||||
}
|
||||
|
||||
return expand;
|
||||
}
|
||||
|
||||
public void ChangeKeyDES(byte key_no, byte[] key_new, byte[] key_current)
|
||||
{
|
||||
if(!CheckKey(key_new))
|
||||
{
|
||||
throw new ArgumentException("key_new is invalid");
|
||||
}
|
||||
|
||||
if (!CheckKey(key_current))
|
||||
{
|
||||
throw new ArgumentException("key_new is invalid");
|
||||
}
|
||||
|
||||
if(GetKeyTypeDES(key_new) != GetKeyTypeDES(key_current))
|
||||
{
|
||||
throw new ArgumentException("key_new and key_current are not same KeyType");
|
||||
}
|
||||
|
||||
byte[] keys_xor = xor(key_new, key_current);
|
||||
|
||||
keys_xor = concatenate(keys_xor, keys_xor);
|
||||
|
||||
CRC32 crc32 = new CRC32();
|
||||
byte[] crc = crc32.Calculate(new byte[] { (byte)APDUInstructions.CHANGE_KEY, key_no }, keys_xor);
|
||||
|
||||
byte[] key_xor_crc = concatenate(keys_xor, crc);
|
||||
|
||||
byte[] key_xor_crc_block = expandToBlockSize(key_xor_crc, 8);
|
||||
|
||||
|
||||
DES des = new DES();
|
||||
|
||||
byte[] key_xor_crc_block_enc = des.Encrypt(key_xor_crc_block, _SessionKey, _IV);
|
||||
|
||||
APDUCommand cmd = new APDUCommand(IsoCase.Case4Short)
|
||||
{
|
||||
CLA = 0x90,
|
||||
INS = (byte)APDUInstructions.CHANGE_KEY,
|
||||
Data = key_xor_crc_block_enc,
|
||||
Le = 0x00
|
||||
};
|
||||
|
||||
APDUResponse response = _Card.Transmit(cmd);
|
||||
|
||||
CheckAPDUResponse(response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -302,6 +444,58 @@ namespace NFC.Mifare_DESFire
|
||||
{
|
||||
throw new Exception("PICC Challenge is not correct answered.");
|
||||
}
|
||||
|
||||
_SessionKey = GenerateDESSesionKey(rndA, rndB);
|
||||
_IV = GenerateDefaultKey(8);
|
||||
}
|
||||
|
||||
private byte[] GenerateDESSesionKey(byte[] rndA, byte[] rndB)
|
||||
{
|
||||
byte[] sesssionkey = new byte[8];
|
||||
|
||||
for(int i = 0; i < sesssionkey.Length; i++)
|
||||
{
|
||||
if(i < 4)
|
||||
{
|
||||
sesssionkey[i] = rndA[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
sesssionkey[i] = rndB[i - 4];
|
||||
}
|
||||
}
|
||||
|
||||
// Set Key Verion of Key to 0x55 to LSB
|
||||
// TODO
|
||||
byte[] key_version = SetKeyVersion(sesssionkey, 0x55);
|
||||
|
||||
return concatenate(key_version, key_version);
|
||||
}
|
||||
|
||||
public byte[] SetKeyVersion(byte[] key, byte keyversion)
|
||||
{
|
||||
byte[] pow2 = new byte[]
|
||||
{
|
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
|
||||
};
|
||||
|
||||
byte[] new_key = new byte[key.Length];
|
||||
key.CopyTo(new_key, 0);
|
||||
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
if((keyversion & pow2[i]) > 0)
|
||||
{
|
||||
new_key[i] = (byte)(new_key[5] | 0x01);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_key[i] = (byte)(new_key[5] & 0x7F);
|
||||
}
|
||||
}
|
||||
|
||||
return new_key;
|
||||
}
|
||||
|
||||
public void ChangeApplicationMasterKey(byte[] aPP_MasterKey)
|
||||
@ -313,7 +507,7 @@ namespace NFC.Mifare_DESFire
|
||||
/// Delete Application by ID
|
||||
/// </summary>
|
||||
/// <param name="id">3 Byte ID</param>
|
||||
public APDUCommand DeleteApplication(UInt32 id)
|
||||
public void DeleteApplication(UInt32 id)
|
||||
{
|
||||
byte[] id_byte = BitConverter.GetBytes(id);
|
||||
|
||||
@ -330,7 +524,8 @@ namespace NFC.Mifare_DESFire
|
||||
Le = 0x00
|
||||
};
|
||||
|
||||
return cmd;
|
||||
APDUResponse response = _Card.Transmit(cmd);
|
||||
CheckAPDUResponse(response);
|
||||
}
|
||||
|
||||
public void ChangeApplicationKey(int v, byte[] aPP_Key_1)
|
||||
|
@ -1,5 +1,6 @@
|
||||
using NFC;
|
||||
using NFC.Crypto;
|
||||
using NFC.ISO7816_4;
|
||||
using NFC.Mifare_DESFire;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
|
@ -7,6 +7,7 @@ using NFC.Readers.PCSC;
|
||||
using System.Threading;
|
||||
using NFC.Mifare_DESFire;
|
||||
using NFC.Mifare_DESFire.Enums;
|
||||
using NFC.ISO7816_4;
|
||||
|
||||
namespace NFC_Test
|
||||
{
|
||||
@ -71,21 +72,21 @@ namespace NFC_Test
|
||||
|
||||
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||
|
||||
APDUCommand cmd = desfire.GetApplicationIDs();
|
||||
//APDUCommand cmd = desfire.GetApplicationIDs();
|
||||
|
||||
APDUResponse response = card.Transmit(cmd);
|
||||
//APDUResponse response = card.Transmit(cmd);
|
||||
|
||||
if (response.StatusWord == NFC.Mifare_DESFire.APDUStatusWords.OK)
|
||||
{
|
||||
UInt32[] ApplicationIDs = desfire.ConvertApplicationIDs(response);
|
||||
//if (response.StatusWord == NFC.Mifare_DESFire.APDUStatusWords.OK)
|
||||
//{
|
||||
// UInt32[] ApplicationIDs = desfire.ConvertApplicationIDs(response);
|
||||
|
||||
foreach(UInt32 id in ApplicationIDs)
|
||||
{
|
||||
Console.WriteLine("0x{0:X3}", id);
|
||||
}
|
||||
// foreach(UInt32 id in ApplicationIDs)
|
||||
// {
|
||||
// Console.WriteLine("0x{0:X3}", id);
|
||||
// }
|
||||
|
||||
transmit_successfully = true;
|
||||
}
|
||||
// transmit_successfully = true;
|
||||
//}
|
||||
|
||||
card.Disconnect();
|
||||
};
|
||||
@ -111,18 +112,18 @@ namespace NFC_Test
|
||||
{
|
||||
card.Connect();
|
||||
|
||||
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||
//MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||
|
||||
APDUCommand cmd = desfire.SelectApplication(applicationID);
|
||||
//APDUCommand cmd = desfire.SelectApplication(applicationID);
|
||||
|
||||
cmd.ToArray();
|
||||
//cmd.ToArray();
|
||||
|
||||
APDUResponse response = card.Transmit(cmd);
|
||||
//APDUResponse response = card.Transmit(cmd);
|
||||
|
||||
if (response.StatusWord == NFC.Mifare_DESFire.APDUStatusWords.OK)
|
||||
{
|
||||
transmit_successfully = true;
|
||||
}
|
||||
//if (response.StatusWord == NFC.Mifare_DESFire.APDUStatusWords.OK)
|
||||
//{
|
||||
// transmit_successfully = true;
|
||||
//}
|
||||
|
||||
card.Disconnect();
|
||||
};
|
||||
@ -136,44 +137,7 @@ namespace NFC_Test
|
||||
reader.CardDiscovered -= handler;
|
||||
}
|
||||
|
||||
[TestCase("ACS ACR122U PICC Interface 0", (UInt32)0xC0FFEE)]
|
||||
public void DeleteApplication(string readerID, UInt32 applicationID)
|
||||
{
|
||||
IHardware hardware = new Hardware();
|
||||
IReader reader = hardware.OpenReader(readerID);
|
||||
|
||||
bool transmit_successfully = false;
|
||||
|
||||
ReaderEventHandler handler = (sender, card) =>
|
||||
{
|
||||
card.Connect();
|
||||
|
||||
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||
|
||||
APDUCommand cmd = desfire.DeleteApplication(applicationID);
|
||||
|
||||
cmd.ToArray();
|
||||
|
||||
APDUResponse response = card.Transmit(cmd);
|
||||
|
||||
if (response.StatusWord == NFC.Mifare_DESFire.APDUStatusWords.OK)
|
||||
{
|
||||
transmit_successfully = true;
|
||||
}
|
||||
|
||||
card.Disconnect();
|
||||
};
|
||||
|
||||
reader.CardDiscovered += handler;
|
||||
reader.Start();
|
||||
|
||||
Assert.AreEqual(true, transmit_successfully);
|
||||
|
||||
reader.Stop();
|
||||
reader.CardDiscovered -= handler;
|
||||
}
|
||||
|
||||
[TestCase("ACS ACR122U PICC Interface 0", (UInt32)0xC0FFEE)]
|
||||
[TestCase("ACS ACR122U PICC Interface 0", (UInt32)0xAAFFEE)]
|
||||
public void CreateApplication(string readerID, UInt32 applicationID)
|
||||
{
|
||||
IHardware hardware = new Hardware();
|
||||
@ -188,7 +152,7 @@ namespace NFC_Test
|
||||
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||
|
||||
byte keysetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.SAMEKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.NOKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE);
|
||||
byte keysetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.AES, FileIdentifies.NOTUSED, 0x01);
|
||||
byte keysetting2 = desfire.GenerateKeySetting2(CryptoOperationsType.TDES, FileIdentifies.NOTUSED, 0x03);
|
||||
|
||||
APDUCommand cmd = desfire.CreateApplication(applicationID, keysetting1, keysetting2);
|
||||
|
||||
@ -213,6 +177,38 @@ namespace NFC_Test
|
||||
reader.CardDiscovered -= handler;
|
||||
}
|
||||
|
||||
[TestCase("ACS ACR122U PICC Interface 0", (UInt32)0xAAFFEE)]
|
||||
public void DeleteApplication(string readerID, UInt32 applicationID)
|
||||
{
|
||||
IHardware hardware = new Hardware();
|
||||
IReader reader = hardware.OpenReader(readerID);
|
||||
|
||||
bool transmit_successfully = false;
|
||||
|
||||
ReaderEventHandler handler = (sender, card) =>
|
||||
{
|
||||
card.Connect();
|
||||
|
||||
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||
|
||||
desfire.SelectApplication(0x000000);
|
||||
desfire.AuthenticateDES(0x00, GenerateDefaultKey(8));
|
||||
desfire.DeleteApplication(applicationID);
|
||||
|
||||
transmit_successfully = true;
|
||||
|
||||
card.Disconnect();
|
||||
};
|
||||
|
||||
reader.CardDiscovered += handler;
|
||||
reader.Start();
|
||||
|
||||
Assert.AreEqual(true, transmit_successfully);
|
||||
|
||||
reader.Stop();
|
||||
reader.CardDiscovered -= handler;
|
||||
}
|
||||
|
||||
public byte[] GenerateDefaultKey(int size)
|
||||
{
|
||||
List<byte> key = new List<byte>();
|
||||
@ -223,6 +219,7 @@ namespace NFC_Test
|
||||
|
||||
return key.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used Default PICC Key with PICC authenticate
|
||||
/// </summary>
|
||||
@ -241,6 +238,7 @@ namespace NFC_Test
|
||||
|
||||
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||
|
||||
desfire.SelectApplication(0x000000);
|
||||
desfire.AuthenticateDES(0x00, GenerateDefaultKey(8));
|
||||
|
||||
transmit_successfully = true;
|
||||
@ -256,5 +254,37 @@ namespace NFC_Test
|
||||
reader.Stop();
|
||||
reader.CardDiscovered -= handler;
|
||||
}
|
||||
|
||||
[TestCase("ACS ACR122U PICC Interface 0")]
|
||||
public void ChangeKey(string readerID)
|
||||
{
|
||||
IHardware hardware = new Hardware();
|
||||
IReader reader = hardware.OpenReader(readerID);
|
||||
|
||||
bool transmit_successfully = false;
|
||||
|
||||
ReaderEventHandler handler = (sender, card) =>
|
||||
{
|
||||
card.Connect();
|
||||
|
||||
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||
|
||||
desfire.SelectApplication(0xAAFFEE);
|
||||
desfire.AuthenticateDES(0x00, GenerateDefaultKey(8));
|
||||
desfire.ChangeKeyDES(0x01, GenerateDefaultKey(8), new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF });
|
||||
|
||||
transmit_successfully = true;
|
||||
|
||||
card.Disconnect();
|
||||
};
|
||||
|
||||
reader.CardDiscovered += handler;
|
||||
reader.Start();
|
||||
|
||||
Assert.AreEqual(true, transmit_successfully);
|
||||
|
||||
reader.Stop();
|
||||
reader.CardDiscovered -= handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user