mirror of
https://gitlab.com/fabinfra/fabaccess/borepin.git
synced 2025-04-20 18:36:31 +02:00
Backup
This commit is contained in:
parent
6a5f521800
commit
d601e9afb3
@ -1,13 +0,0 @@
|
|||||||
using PCSC;
|
|
||||||
using PCSC.Iso7816;
|
|
||||||
|
|
||||||
namespace NFC
|
|
||||||
{
|
|
||||||
public class APDUCommand : CommandApdu
|
|
||||||
{
|
|
||||||
public APDUCommand(IsoCase isoCase) : base(isoCase, SCardProtocol.Any)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using NFC.ISO7816_4;
|
||||||
|
|
||||||
namespace NFC
|
namespace NFC
|
||||||
{
|
{
|
||||||
|
47
NFC/ISO7816-4/APDUCommand.cs
Normal file
47
NFC/ISO7816-4/APDUCommand.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using PCSC;
|
||||||
|
using PCSC.Iso7816;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NFC.ISO7816_4
|
||||||
|
{
|
||||||
|
public class APDUCommand : CommandApdu
|
||||||
|
{
|
||||||
|
public APDUCommand(IsoCase isoCase) : base(isoCase, SCardProtocol.Any)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return obj is APDUCommand command &&
|
||||||
|
Case == command.Case &&
|
||||||
|
Protocol == command.Protocol &&
|
||||||
|
CLA == command.CLA &&
|
||||||
|
INS == command.INS &&
|
||||||
|
P1 == command.P1 &&
|
||||||
|
P2 == command.P2 &&
|
||||||
|
EqualityComparer<byte[]>.Default.Equals(Data, command.Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
HashCode hash = new HashCode();
|
||||||
|
hash.Add(Case);
|
||||||
|
hash.Add(Protocol);
|
||||||
|
hash.Add(IsValid);
|
||||||
|
hash.Add(CLA);
|
||||||
|
hash.Add(INS);
|
||||||
|
hash.Add(P1);
|
||||||
|
hash.Add(P2);
|
||||||
|
hash.Add(P1P2);
|
||||||
|
hash.Add(Data);
|
||||||
|
hash.Add(Lc);
|
||||||
|
hash.Add(P3);
|
||||||
|
hash.Add(Le);
|
||||||
|
hash.Add(ExpectedResponseLength);
|
||||||
|
hash.Add(IsValid);
|
||||||
|
return hash.ToHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,42 +1,44 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NFC.Mifare_DESFire;
|
using NFC.Mifare_DESFire;
|
||||||
|
|
||||||
namespace NFC
|
namespace NFC.ISO7816_4
|
||||||
{
|
{
|
||||||
public class APDUResponse
|
public class APDUResponse
|
||||||
{
|
{
|
||||||
/// <summary>
|
#region constructor
|
||||||
/// ISO 7816 - Body - Body
|
|
||||||
/// </summary>
|
|
||||||
public byte[] Body { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ISO 7816 - SW1 - Status Word 1
|
|
||||||
/// </summary>
|
|
||||||
public byte SW1 { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ISO 7816 - SW2 - Status Word 2
|
|
||||||
/// </summary>
|
|
||||||
public byte SW2 { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new APDUResponse from the raw received data.
|
|
||||||
/// </summary>
|
|
||||||
public APDUResponse(byte[] raw) {
|
|
||||||
Body = raw.Take(raw.Length-1).ToArray();
|
|
||||||
SW1 = raw[raw.Length - 2];
|
|
||||||
SW2 = raw[raw.Length - 3];
|
|
||||||
}
|
|
||||||
|
|
||||||
public APDUResponse()
|
public APDUResponse()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new APDUResponse from the raw received data.
|
||||||
|
/// </summary>
|
||||||
|
public APDUResponse(byte[] raw)
|
||||||
|
{
|
||||||
|
Body = raw.Take(raw.Length - 1).ToArray();
|
||||||
|
SW1 = raw[raw.Length - 2];
|
||||||
|
SW2 = raw[raw.Length - 3];
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
/// <summary>
|
||||||
|
/// ISO 7816-4-4 - Body - Body
|
||||||
|
/// </summary>
|
||||||
|
public byte[] Body { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ISO 7816-4 - SW1 - Status Word 1
|
||||||
|
/// </summary>
|
||||||
|
public byte SW1 { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ISO 7816-4 - SW2 - Status Word 2
|
||||||
|
/// </summary>
|
||||||
|
public byte SW2 { get; set; }
|
||||||
|
|
||||||
public APDUStatusWords StatusWord
|
public APDUStatusWords StatusWord
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -104,5 +106,6 @@ namespace NFC
|
|||||||
return SW2;
|
return SW2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace NFC.Mifare_DESFire
|
namespace NFC.Mifare_DESFire
|
||||||
{
|
{
|
@ -1,35 +1,223 @@
|
|||||||
using NFC.Crypto;
|
using NFC.Crypto;
|
||||||
|
using NFC.ISO7816_4;
|
||||||
using NFC.Mifare_DESFire.Enums;
|
using NFC.Mifare_DESFire.Enums;
|
||||||
|
using Org.BouncyCastle.Asn1.Crmf;
|
||||||
using PCSC.Iso7816;
|
using PCSC.Iso7816;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace NFC.Mifare_DESFire
|
namespace NFC.Mifare_DESFire
|
||||||
{
|
{
|
||||||
|
|
||||||
public class MifareDESFire
|
public class MIFARE_DESFire
|
||||||
{
|
{
|
||||||
public byte[] GenerateDefaultKey(int size)
|
// Docs https://hackmd.io/qATu8uYdRnOC40aFrB9afg
|
||||||
{
|
|
||||||
List<byte> key = new List<byte>();
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
key.Add(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return key.ToArray();
|
#region Contructors
|
||||||
}
|
/// <summary>
|
||||||
|
/// Construct MIFRARE_DESFire Object with ICard Interface
|
||||||
private ICard _Card;
|
/// </summary>
|
||||||
|
/// <param name="card">Implementation of ICard, only transmit is used</param>
|
||||||
public MifareDESFire(ICard card)
|
public MIFARE_DESFire(ICard card)
|
||||||
{
|
{
|
||||||
_Card = card;
|
_Card = card;
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
/// <summary>
|
||||||
|
/// ICard Implementation used to transmit APDUCommands and recive APDUResponses
|
||||||
|
/// </summary>
|
||||||
|
private ICard _Card;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
/// <summary>
|
||||||
|
/// Generate Byte Array filled with 0
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="size">Size of Array</param>
|
||||||
|
public byte[] GenerateDefaultKey(uint size)
|
||||||
|
{
|
||||||
|
byte[] key = new byte[size];
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
key.[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts byte[] to string with HEX Code
|
||||||
|
/// No 0x is created
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">Data</param>
|
||||||
|
public string ConvertToHexString(byte[] data)
|
||||||
|
{
|
||||||
|
return BitConverter.ToString(data).Replace("-", string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CheckAPDUResponse(APDUResponse response)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Methods for Crypto Operation
|
||||||
|
/// <summary>
|
||||||
|
/// Return a copy of the last Block of data
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">Data compatible to blocksize</param>
|
||||||
|
/// <param name="blocksize">Size of Block, default is 8</param>
|
||||||
|
public byte[] GetLastBlock(byte[] data, uint blocksize = 8)
|
||||||
|
{
|
||||||
|
if(data.Length % blocksize != 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(string.Format("Data is not compatible with blocksize(data(length):{0}, blocksize:{1}", data.Length, blocksize));
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] block = new byte[blocksize];
|
||||||
|
|
||||||
|
for (int i = 0; i < blocksize; i++)
|
||||||
|
{
|
||||||
|
block[i] = data[data.Length - blocksize + i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rotates Array to the left
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">Data</param>
|
||||||
|
/// <returns>Copy of data</returns>
|
||||||
|
public byte[] rotateLeft(byte[] data)
|
||||||
|
{
|
||||||
|
byte[] rotate = new byte[data.Length];
|
||||||
|
data.CopyTo(rotate, 0);
|
||||||
|
|
||||||
|
byte tmp = rotate[0];
|
||||||
|
for (var i = 0; i < rotate.Length - 1; i++)
|
||||||
|
{
|
||||||
|
rotate[i] = rotate[i + 1];
|
||||||
|
}
|
||||||
|
rotate[rotate.Length - 1] = tmp;
|
||||||
|
|
||||||
|
return rotate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rotates Array to the right
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">Data</param>
|
||||||
|
/// <returns>Copy of data</returns>
|
||||||
|
public byte[] rotateRight(byte[] data)
|
||||||
|
{
|
||||||
|
byte[] rotate = new byte[data.Length];
|
||||||
|
data.CopyTo(rotate, 0);
|
||||||
|
|
||||||
|
byte tmp = rotate[rotate.Length - 1];
|
||||||
|
for (var i = rotate.Length - 1; i > 0; i--)
|
||||||
|
{
|
||||||
|
rotate[i] = rotate[i - 1];
|
||||||
|
}
|
||||||
|
rotate[0] = tmp;
|
||||||
|
|
||||||
|
return rotate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Concatenates two Arrays, Array A start at index 0
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">Array A</param>
|
||||||
|
/// <param name="b">Array B</param>
|
||||||
|
/// <returns>Copy of Data</returns>
|
||||||
|
public byte[] concatenate(byte[] a, byte[] b)
|
||||||
|
{
|
||||||
|
byte[] c = new byte[a.Length + b.Length];
|
||||||
|
a.CopyTo(c, 0);
|
||||||
|
b.CopyTo(c, a.Length);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region DESFire Commands
|
||||||
|
/// <summary>
|
||||||
|
/// Get Application IDs from Card
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>AIDs as Array</returns>
|
||||||
|
public UInt32[] GetApplicationIDs()
|
||||||
|
{
|
||||||
|
APDUCommand cmd = new APDUCommand(IsoCase.Case2Short)
|
||||||
|
{
|
||||||
|
CLA = 0x90,
|
||||||
|
INS = (byte)APDUInstructions.GET_APPLICATION_IDS
|
||||||
|
};
|
||||||
|
|
||||||
|
APDUResponse response = _Card.Transmit(cmd);
|
||||||
|
|
||||||
|
CheckAPDUResponse(response);
|
||||||
|
|
||||||
|
if (response.Body.Length % 3 != 0)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Format("Invalid body length (was: {0}).", response.Body.Length));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(response.Body.Length == 0)
|
||||||
|
{
|
||||||
|
throw new Exception("Missing PICC Entry 0x000000.");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<UInt32> applicationIDs = new List<UInt32>();
|
||||||
|
|
||||||
|
for (int i = 0; i < response.Body.Length; i += 3)
|
||||||
|
{
|
||||||
|
UInt32 new_applicationID = 0;
|
||||||
|
new_applicationID = (UInt32)((response.Body[i] << 16) + (response.Body[i + 1] << 8) + response.Body[i + 2]);
|
||||||
|
applicationIDs.Add(new_applicationID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return applicationIDs.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Select Application by AID
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="aid">3 Byte AID</param>
|
||||||
|
public void SelectApplication(UInt32 aid)
|
||||||
|
{
|
||||||
|
byte[] id_byte = BitConverter.GetBytes(aid);
|
||||||
|
|
||||||
|
APDUCommand cmd = new APDUCommand(IsoCase.Case3Short)
|
||||||
|
{
|
||||||
|
CLA = 0x90,
|
||||||
|
INS = (byte)APDUInstructions.SELECT_APPLICATION,
|
||||||
|
Data = new byte[]
|
||||||
|
{
|
||||||
|
id_byte[0],
|
||||||
|
id_byte[1],
|
||||||
|
id_byte[2]
|
||||||
|
},
|
||||||
|
Le = 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
APDUResponse response = _Card.Transmit(cmd);
|
||||||
|
|
||||||
|
CheckAPDUResponse(response);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create new Application with AID
|
/// Create new Application with AID
|
||||||
@ -40,36 +228,6 @@ namespace NFC.Mifare_DESFire
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public APDUCommand GetApplicationIDs()
|
|
||||||
{
|
|
||||||
APDUCommand cmd = new APDUCommand(IsoCase.Case2Short)
|
|
||||||
{
|
|
||||||
CLA = 0x90,
|
|
||||||
INS = (byte)APDUInstructions.GET_APPLICATION_IDS
|
|
||||||
};
|
|
||||||
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UInt32[] ConvertApplicationIDs(APDUResponse response)
|
|
||||||
{
|
|
||||||
if(response.Body.Length % 3 != 0)
|
|
||||||
{
|
|
||||||
throw new Exception("Invalid Body Length.");
|
|
||||||
}
|
|
||||||
|
|
||||||
List<UInt32> applicationIDs = new List<UInt32>();
|
|
||||||
|
|
||||||
for(int i = 0; i < response.Body.Length; i += 3)
|
|
||||||
{
|
|
||||||
UInt32 new_applicationID = 0;
|
|
||||||
new_applicationID = (UInt32)((response.Body[i] << 16) + (response.Body[i + 1] << 8) + response.Body[i + 2]);
|
|
||||||
applicationIDs.Add(new_applicationID);
|
|
||||||
}
|
|
||||||
|
|
||||||
return applicationIDs.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Format()
|
public void Format()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@ -80,7 +238,9 @@ namespace NFC.Mifare_DESFire
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key_id">0x01 - 0x0D</param>
|
/// <param name="key_id">0x01 - 0x0D</param>
|
||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
public void Authenticate(byte key_id, byte[] key)
|
|
||||||
|
// TODO
|
||||||
|
public void AuthenticateDES(byte key_id, byte[] key)
|
||||||
{
|
{
|
||||||
APDUCommand cmd_challange_request = new APDUCommand(IsoCase.Case4Short)
|
APDUCommand cmd_challange_request = new APDUCommand(IsoCase.Case4Short)
|
||||||
{
|
{
|
||||||
@ -94,30 +254,30 @@ namespace NFC.Mifare_DESFire
|
|||||||
APDUResponse response = _Card.Transmit(cmd_challange_request);
|
APDUResponse response = _Card.Transmit(cmd_challange_request);
|
||||||
|
|
||||||
byte[] rndB_enc = response.Body;
|
byte[] rndB_enc = response.Body;
|
||||||
Console.WriteLine("rndB_enc: {0}", toHexString(rndB_enc));
|
Console.WriteLine("rndB_enc: {0}", ConvertToHexString(rndB_enc));
|
||||||
|
|
||||||
DES des = new DES();
|
DES des = new DES();
|
||||||
byte[] rndB = des.Decrypt(rndB_enc, key, GenerateDefaultKey(8));
|
byte[] rndB = des.Decrypt(rndB_enc, key, GenerateDefaultKey(8));
|
||||||
Console.WriteLine("rndB: {0}", toHexString(rndB));
|
Console.WriteLine("rndB: {0}", ConvertToHexString(rndB));
|
||||||
|
|
||||||
byte[] iv = new byte[8];
|
byte[] iv = new byte[8];
|
||||||
rndB.CopyTo(iv, 0);
|
rndB.CopyTo(iv, 0);
|
||||||
|
|
||||||
byte[] rndB_rl = rotateLeft(rndB);
|
byte[] rndB_rl = rotateLeft(rndB);
|
||||||
Console.WriteLine("rndB_enc: {0}", toHexString(rndB_rl));
|
Console.WriteLine("rndB_enc: {0}", ConvertToHexString(rndB_rl));
|
||||||
|
|
||||||
byte[] rndA = new byte[]
|
byte[] rndA = new byte[]
|
||||||
{
|
{
|
||||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
|
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
|
||||||
};
|
};
|
||||||
Console.WriteLine("rndA: {0}", toHexString(rndA));
|
Console.WriteLine("rndA: {0}", ConvertToHexString(rndA));
|
||||||
|
|
||||||
byte[] rndAB = concatenate(rndA, rndB_rl);
|
byte[] rndAB = concatenate(rndA, rndB_rl);
|
||||||
Console.WriteLine("rndAB: {0}", toHexString(rndAB));
|
Console.WriteLine("rndAB: {0}", ConvertToHexString(rndAB));
|
||||||
|
|
||||||
byte[] rndAB_enc = des.Encrypt(rndAB, key, rndB_enc);
|
byte[] rndAB_enc = des.Encrypt(rndAB, key, rndB_enc);
|
||||||
Console.WriteLine("rndA_rndB_enc: {0}", toHexString(rndAB_enc));
|
Console.WriteLine("rndA_rndB_enc: {0}", ConvertToHexString(rndAB_enc));
|
||||||
iv = lastBlock(rndAB_enc);
|
iv = GetLastBlock(rndAB_enc);
|
||||||
|
|
||||||
APDUCommand cmd_challange_response = new APDUCommand(IsoCase.Case4Short)
|
APDUCommand cmd_challange_response = new APDUCommand(IsoCase.Case4Short)
|
||||||
{
|
{
|
||||||
@ -125,116 +285,25 @@ namespace NFC.Mifare_DESFire
|
|||||||
INS = (byte)0xAF,
|
INS = (byte)0xAF,
|
||||||
Data = rndAB_enc
|
Data = rndAB_enc
|
||||||
};
|
};
|
||||||
Console.WriteLine("cmd_challange_response: {0}", toHexString(cmd_challange_response.ToArray()));
|
Console.WriteLine("cmd_challange_response: {0}", ConvertToHexString(cmd_challange_response.ToArray()));
|
||||||
|
|
||||||
response = _Card.Transmit(cmd_challange_response);
|
response = _Card.Transmit(cmd_challange_response);
|
||||||
|
|
||||||
byte[] encryptedRndAFromCard = response.Body;
|
byte[] encryptedRndAFromCard = response.Body;
|
||||||
Console.WriteLine("encryptedRndAFromCard: {0}", toHexString(encryptedRndAFromCard));
|
Console.WriteLine("encryptedRndAFromCard: {0}", ConvertToHexString(encryptedRndAFromCard));
|
||||||
|
|
||||||
byte[] rotatedRndAFromCard = des.Decrypt(encryptedRndAFromCard, key, iv);
|
byte[] rotatedRndAFromCard = des.Decrypt(encryptedRndAFromCard, key, iv);
|
||||||
Console.WriteLine("rotatedRndAFromCard: {0}", toHexString(rotatedRndAFromCard));
|
Console.WriteLine("rotatedRndAFromCard: {0}", ConvertToHexString(rotatedRndAFromCard));
|
||||||
|
|
||||||
byte[] rndAFromCard = rotateRight(rotatedRndAFromCard);
|
byte[] rndAFromCard = rotateRight(rotatedRndAFromCard);
|
||||||
Console.WriteLine("rndAFromCard: {0}", toHexString(rndAFromCard));
|
Console.WriteLine("rndAFromCard: {0}", ConvertToHexString(rndAFromCard));
|
||||||
|
|
||||||
if (!rndA.SequenceEqual(rndAFromCard))
|
if (!rndA.SequenceEqual(rndAFromCard))
|
||||||
{
|
{
|
||||||
throw new Exception("???");
|
throw new Exception("PICC Challenge is not correct answered.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] lastBlock(byte[] data)
|
|
||||||
{
|
|
||||||
byte[] block = new byte[8];
|
|
||||||
|
|
||||||
for(int i = 0; i < block.Length; i++)
|
|
||||||
{
|
|
||||||
block[i] = data[data.Length - block.Length + i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
public byte[] exclusiveOR(byte[] a, byte[] b)
|
|
||||||
{
|
|
||||||
byte[] c = new byte[a.Length];
|
|
||||||
|
|
||||||
for (int i = 0; i < a.Length; i++)
|
|
||||||
{
|
|
||||||
c[i] = (byte)(a[i] ^ b[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String toHexString(byte[] data)
|
|
||||||
{
|
|
||||||
return BitConverter.ToString(data).Replace("-", string.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] rotateLeft(byte[] data)
|
|
||||||
{
|
|
||||||
byte[] rotate = new byte[data.Length];
|
|
||||||
data.CopyTo(rotate, 0);
|
|
||||||
|
|
||||||
byte temp = rotate[0];
|
|
||||||
for (var i = 0; i < rotate.Length - 1; i++)
|
|
||||||
{
|
|
||||||
rotate[i] = rotate[i + 1];
|
|
||||||
}
|
|
||||||
rotate[rotate.Length - 1] = temp;
|
|
||||||
|
|
||||||
return rotate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] rotateRight(byte[] data)
|
|
||||||
{
|
|
||||||
byte[] rotate = new byte[data.Length];
|
|
||||||
data.CopyTo(rotate, 0);
|
|
||||||
|
|
||||||
byte temp = rotate[rotate.Length - 1];
|
|
||||||
for (var i = rotate.Length - 1; i > 0; i--)
|
|
||||||
{
|
|
||||||
rotate[i] = rotate[i - 1];
|
|
||||||
}
|
|
||||||
rotate[0] = temp;
|
|
||||||
|
|
||||||
return rotate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] concatenate(byte[] a, byte[] b)
|
|
||||||
{
|
|
||||||
byte[] c = new byte[a.Length + b.Length];
|
|
||||||
a.CopyTo(c, 0);
|
|
||||||
b.CopyTo(c, a.Length);
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Select Application by ID
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">3 Byte ID</param>
|
|
||||||
public APDUCommand SelectApplication(UInt32 id)
|
|
||||||
{
|
|
||||||
byte[] id_byte = BitConverter.GetBytes(id);
|
|
||||||
|
|
||||||
APDUCommand cmd = new APDUCommand(IsoCase.Case4Short)
|
|
||||||
{
|
|
||||||
CLA = 0x90,
|
|
||||||
INS = (byte)APDUInstructions.SELECT_APPLICATION,
|
|
||||||
Data = new byte[]
|
|
||||||
{
|
|
||||||
id_byte[0],
|
|
||||||
id_byte[1],
|
|
||||||
id_byte[2]
|
|
||||||
},
|
|
||||||
Le = 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ChangeApplicationMasterKey(byte[] aPP_MasterKey)
|
public void ChangeApplicationMasterKey(byte[] aPP_MasterKey)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
@ -1,5 +1,6 @@
|
|||||||
using PCSC;
|
using PCSC;
|
||||||
using PCSC.Iso7816;
|
using PCSC.Iso7816;
|
||||||
|
using NFC.ISO7816_4;
|
||||||
|
|
||||||
namespace NFC.Readers.PCSC
|
namespace NFC.Readers.PCSC
|
||||||
{
|
{
|
||||||
|
@ -55,7 +55,7 @@ namespace NFC_Test
|
|||||||
[Test]
|
[Test]
|
||||||
public void concatenate()
|
public void concatenate()
|
||||||
{
|
{
|
||||||
MifareDESFire mifareDESFire = new MifareDESFire(null);
|
MIFARE_DESFire mifareDESFire = new MIFARE_DESFire(null);
|
||||||
|
|
||||||
byte[] rndA = new byte[]
|
byte[] rndA = new byte[]
|
||||||
{
|
{
|
||||||
@ -121,9 +121,9 @@ namespace NFC_Test
|
|||||||
card.Transmit(cmd_getchallange).ReturnsForAnyArgs(response);
|
card.Transmit(cmd_getchallange).ReturnsForAnyArgs(response);
|
||||||
card.Transmit(cmd_answerchallange).Returns(response2);
|
card.Transmit(cmd_answerchallange).Returns(response2);
|
||||||
|
|
||||||
MifareDESFire mifareDESFire = new MifareDESFire(card);
|
MIFARE_DESFire mifareDESFire = new MIFARE_DESFire(card);
|
||||||
|
|
||||||
mifareDESFire.Authenticate(0x00, mifareDESFire.GenerateDefaultKey(16));
|
mifareDESFire.AuthenticateDES(0x00, mifareDESFire.GenerateDefaultKey(16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace NFC_Test
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class MifareDESFire_Commands
|
public class MifareDESFire_Commands
|
||||||
{
|
{
|
||||||
private MifareDESFire _MifareDESFire;
|
private MIFARE_DESFire _MifareDESFire;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp()
|
public void SetUp()
|
||||||
|
@ -69,7 +69,7 @@ namespace NFC_Test
|
|||||||
{
|
{
|
||||||
card.Connect();
|
card.Connect();
|
||||||
|
|
||||||
MifareDESFire desfire = new MifareDESFire(card);
|
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||||
|
|
||||||
APDUCommand cmd = desfire.GetApplicationIDs();
|
APDUCommand cmd = desfire.GetApplicationIDs();
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ namespace NFC_Test
|
|||||||
{
|
{
|
||||||
card.Connect();
|
card.Connect();
|
||||||
|
|
||||||
MifareDESFire desfire = new MifareDESFire(card);
|
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||||
|
|
||||||
APDUCommand cmd = desfire.SelectApplication(applicationID);
|
APDUCommand cmd = desfire.SelectApplication(applicationID);
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ namespace NFC_Test
|
|||||||
{
|
{
|
||||||
card.Connect();
|
card.Connect();
|
||||||
|
|
||||||
MifareDESFire desfire = new MifareDESFire(card);
|
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||||
|
|
||||||
APDUCommand cmd = desfire.DeleteApplication(applicationID);
|
APDUCommand cmd = desfire.DeleteApplication(applicationID);
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ namespace NFC_Test
|
|||||||
{
|
{
|
||||||
card.Connect();
|
card.Connect();
|
||||||
|
|
||||||
MifareDESFire desfire = new MifareDESFire(card);
|
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||||
|
|
||||||
byte keysetting1 = desfire.GenerateKeySetting1(ChangeApplicationKey.SAMEKEY, ChangeMasterKeySettings.WITHMASTERKEY, CreateDeleteFile.NOKEY, FileDirectoryAccess.NOKEY, ChangeMasterKey.CHANGEABLE);
|
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.AES, FileIdentifies.NOTUSED, 0x01);
|
||||||
@ -239,9 +239,9 @@ namespace NFC_Test
|
|||||||
{
|
{
|
||||||
card.Connect();
|
card.Connect();
|
||||||
|
|
||||||
MifareDESFire desfire = new MifareDESFire(card);
|
MIFARE_DESFire desfire = new MIFARE_DESFire(card);
|
||||||
|
|
||||||
desfire.Authenticate(0x00, GenerateDefaultKey(8));
|
desfire.AuthenticateDES(0x00, GenerateDefaultKey(8));
|
||||||
|
|
||||||
transmit_successfully = true;
|
transmit_successfully = true;
|
||||||
|
|
||||||
|
@ -54,9 +54,9 @@ namespace NFC_Test
|
|||||||
{
|
{
|
||||||
card.Connect();
|
card.Connect();
|
||||||
|
|
||||||
MifareDESFire mifareDESFire = new MifareDESFire(card);
|
MIFARE_DESFire mifareDESFire = new MIFARE_DESFire(card);
|
||||||
|
|
||||||
mifareDESFire.Authenticate(0x01, PICC_MasterKey);
|
mifareDESFire.AuthenticateDES(0x01, PICC_MasterKey);
|
||||||
|
|
||||||
mifareDESFire.Format();
|
mifareDESFire.Format();
|
||||||
|
|
||||||
@ -86,16 +86,16 @@ namespace NFC_Test
|
|||||||
{
|
{
|
||||||
card.Connect();
|
card.Connect();
|
||||||
|
|
||||||
MifareDESFire mifareDESFire = new MifareDESFire(card);
|
MIFARE_DESFire mifareDESFire = new MIFARE_DESFire(card);
|
||||||
|
|
||||||
mifareDESFire.Authenticate(0x01, APP_MasterKey);
|
mifareDESFire.AuthenticateDES(0x01, APP_MasterKey);
|
||||||
mifareDESFire.CreateApplication(FabAccessAID);
|
mifareDESFire.CreateApplication(FabAccessAID);
|
||||||
mifareDESFire.SelectApplication(FabAccessAID);
|
mifareDESFire.SelectApplication(FabAccessAID);
|
||||||
|
|
||||||
mifareDESFire.Authenticate(0x00, Empty_Key);
|
mifareDESFire.AuthenticateDES(0x00, Empty_Key);
|
||||||
mifareDESFire.ChangeApplicationMasterKey(APP_MasterKey);
|
mifareDESFire.ChangeApplicationMasterKey(APP_MasterKey);
|
||||||
|
|
||||||
mifareDESFire.Authenticate(0x00, APP_MasterKey);
|
mifareDESFire.AuthenticateDES(0x00, APP_MasterKey);
|
||||||
mifareDESFire.ChangeApplicationKey(0x01, APP_Key_1);
|
mifareDESFire.ChangeApplicationKey(0x01, APP_Key_1);
|
||||||
|
|
||||||
connected_successfully = true;
|
connected_successfully = true;
|
||||||
@ -125,10 +125,10 @@ namespace NFC_Test
|
|||||||
{
|
{
|
||||||
card.Connect();
|
card.Connect();
|
||||||
|
|
||||||
MifareDESFire mifareDESFire = new MifareDESFire(card);
|
MIFARE_DESFire mifareDESFire = new MIFARE_DESFire(card);
|
||||||
|
|
||||||
mifareDESFire.SelectApplication(FabAccessAID);
|
mifareDESFire.SelectApplication(FabAccessAID);
|
||||||
mifareDESFire.Authenticate(0x00, Empty_Key);
|
mifareDESFire.AuthenticateDES(0x00, Empty_Key);
|
||||||
UInt16 fileAccessRight = mifareDESFire.GenerateFileAccessRight(AccessRights.FREE, 0x00, 0x00, 0x00);
|
UInt16 fileAccessRight = mifareDESFire.GenerateFileAccessRight(AccessRights.FREE, 0x00, 0x00, 0x00);
|
||||||
mifareDESFire.CreateFile(FabAccessIdentFileID, FileCommunication.PLAIN, fileAccessRight, (UInt32)0x90);
|
mifareDESFire.CreateFile(FabAccessIdentFileID, FileCommunication.PLAIN, fileAccessRight, (UInt32)0x90);
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ namespace NFC_Test
|
|||||||
{
|
{
|
||||||
card.Connect();
|
card.Connect();
|
||||||
|
|
||||||
MifareDESFire mifareDESFire = new MifareDESFire(card);
|
MIFARE_DESFire mifareDESFire = new MIFARE_DESFire(card);
|
||||||
|
|
||||||
mifareDESFire.SelectApplication(FabAccessAID);
|
mifareDESFire.SelectApplication(FabAccessAID);
|
||||||
byte[] filedata = mifareDESFire.ReadData(FabAccessIdentFileID, 0x00000000, 0x00000000);
|
byte[] filedata = mifareDESFire.ReadData(FabAccessIdentFileID, 0x00000000, 0x00000000);
|
||||||
@ -172,7 +172,7 @@ namespace NFC_Test
|
|||||||
|
|
||||||
Console.WriteLine(userdomain);
|
Console.WriteLine(userdomain);
|
||||||
|
|
||||||
mifareDESFire.Authenticate(0x01, APP_Key_1);
|
mifareDESFire.AuthenticateDES(0x01, APP_Key_1);
|
||||||
|
|
||||||
connected_successfully = true;
|
connected_successfully = true;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user