我正在尝试通过PcSc-Sharp创建一个用于在Mifare1K卡上写/读的c#课程。我得到了“ATR”数据,但我不知道如何从中发出Ndef消息。
我还调查了Mifare - 图书馆,但样本似乎是错误的(每个“附加卡事件”都无法读取扇区)。 所以我的问题是:有没有人知道Windows的工作方法/库,这对我来说是低级别的东西?
编辑:我尝试了PcSc包中的Mifare样本。在那里我无法加载密钥:using (var context = new SCardContext())
{
context.Establish(SCardScope.System);
var readerNames = context.GetReaders();
if (readerNames == null || readerNames.Length < 1)
{
Console.WriteLine("You need at least one reader in order to run this example.");
Console.ReadKey();
return;
}
var readerName = ChooseReader(readerNames);
if (readerName == null)
{
return;
}
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
new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } // key
);
if (!loadKeySuccessful)
{
throw new Exception("LOAD KEY failed.");
}
// ... some more actions here ...
}
}
有人知道,如果loadKey参数没问题吗?
答案 0 :(得分:0)
更新:我只能读取唯一的卡ID,而不是NDef标签。所以这是我的解决方案:
<强> PcscWrapper.cs 强>
internal class PcscWrapper : IDisposable
{
private SCardMonitor pcscMonitor;
private string lastUniqueId;
private NfcEventType lastEventType;
public string[] ReaderNames { get; private set; }
internal event EventHandler<NfcEventArgs> PcScNfcEventReceived;
internal bool CheckReaders()
{
using (var context = new SCardContext())
{
context.Establish(SCardScope.System);
ReaderNames = context.GetReaders();
context.Release();
}
if (ReaderNames == null || ReaderNames.Length < 1)
{
Debug.WriteLine("PcscWrapper: No readers installed.");
return false;
}
return true;
}
internal bool Initialize(out NfcDeviceType type)
{
type = NfcDeviceType.None;
// Start Pcsc
pcscMonitor = new SCardMonitor(ContextFactory.Instance, SCardScope.System);
pcscMonitor.MonitorException += (s, a) => OnPcScExceptionReceived(s, a);
pcscMonitor.StatusChanged += (s, a) => OnPcScStatusChangeEventReceived(s, a);
pcscMonitor.CardInserted += (s, a) => OnPcScCardStatusEventReceived(s, a);
pcscMonitor.CardRemoved += (s, a) => OnPcScCardStatusEventReceived(s, a);
foreach (var reader in ReaderNames)
{
Debug.WriteLine("PcscWrapper: Init Listening on reader " + reader + ".");
}
pcscMonitor.Start(ReaderNames);
type = NfcDeviceType.Pcsc;
return true;
}
private void OnPcScExceptionReceived(object s, PCSCException a)
{
var eventargs = new NfcEventArgs();
eventargs.Type = NfcEventType.Unknown;
eventargs.Data = $"Error: {a.Message} ({a.SCardError.ToString()})";
PcScNfcEventReceived?.Invoke(this, eventargs);
}
private void OnPcScStatusChangeEventReceived(object s, StatusChangeEventArgs a)
{
RaisePcScEvent(a.NewState, a.ReaderName);
}
private void OnPcScCardStatusEventReceived(object s, CardStatusEventArgs a)
{
RaisePcScEvent(a.State, a.ReaderName);
}
private void RaisePcScEvent(SCRState state, string readerName)
{
bool doRaiseEvent = true;
var eventargs = new NfcEventArgs();
eventargs.ReaderName = readerName;
eventargs.Data = $"New State for {readerName}: {state.ToString()}";
switch (state)
{
case SCRState.Changed:
eventargs.Type = NfcEventType.StatusChanged;
break;
case SCRState.Empty:
case SCRState.Unavailable:
eventargs.Type = NfcEventType.Disconnected;
lastUniqueId = null;
break;
case SCRState.Present:
eventargs.Type = NfcEventType.Connected;
eventargs.UniqueCardID = state.CardIsPresent() ? GetUid(readerName) : null;
if (eventargs.UniqueCardID == lastUniqueId)
{
doRaiseEvent = false;
}
break;
case SCRState.Unknown:
eventargs.Type = NfcEventType.Unknown;
break;
default:
doRaiseEvent = false;
break;
}
if (doRaiseEvent && lastEventType != eventargs.Type)
{
string debugText = $"PcscWrapper: {eventargs.Type.ToString()} UID: ";
debugText += eventargs.UniqueCardID ?? "N/A";
Debug.WriteLine(debugText);
System.Threading.Thread.Sleep(200);
PcScNfcEventReceived?.Invoke(this, eventargs);
lastUniqueId = eventargs.UniqueCardID;
lastEventType = eventargs.Type;
}
}
private string GetUid(string readerName)
{
using (var context = new SCardContext())
{
context.Establish(SCardScope.System);
using (var rfidReader = new SCardReader(context))
{
var sc = rfidReader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any);
if (sc != SCardError.Success)
{
Debug.WriteLine($"PcscWrapper: Could not connect to reader {readerName}:\n{SCardHelper.StringifyError(sc)}");
return null;
}
var apdu = new CommandApdu(IsoCase.Case2Short, rfidReader.ActiveProtocol)
{
CLA = 0xFF,
Instruction = InstructionCode.GetData,
P1 = 0x00,
P2 = 0x00,
Le = 0 // We don't know the ID tag size
};
sc = rfidReader.BeginTransaction();
if (sc != SCardError.Success)
{
Debug.WriteLine("PcscWrapper: Could not begin transaction.");
return null;
}
var receivePci = new SCardPCI(); // IO returned protocol control information.
var sendPci = SCardPCI.GetPci(rfidReader.ActiveProtocol);
var receiveBuffer = new byte[256];
var command = apdu.ToArray();
sc = rfidReader.Transmit(
sendPci, // Protocol Control Information (T0, T1 or Raw)
command, // command APDU
receivePci, // returning Protocol Control Information
ref receiveBuffer); // data buffer
if (sc != SCardError.Success)
{
Debug.WriteLine("Error: " + SCardHelper.StringifyError(sc));
}
var responseApdu = new ResponseApdu(receiveBuffer, IsoCase.Case2Short, rfidReader.ActiveProtocol);
rfidReader.EndTransaction(SCardReaderDisposition.Leave);
rfidReader.Disconnect(SCardReaderDisposition.Reset);
if (responseApdu.HasData)
{
string uid = BitConverter.ToString(responseApdu.GetData()).Replace("-", "").ToUpper();
return (uid);
}
}
}
return null;
}
public void Dispose()
{
if (pcscMonitor != null)
{
if (pcscMonitor.Monitoring)
{
pcscMonitor.Cancel();
}
pcscMonitor.Dispose();
}
}
}
也许它对某人有用。