使⽤ACR122UNFC读卡器对M1卡进⾏读写操作(可以读写中 ⽂)
因为项⽬需要,第⼀次接触到了ACR122U NFC读卡器(⾮接触式)和M1卡,⾸先介绍⼀下想要读写应该知道的基本知识。
我就根据我的理解先叙述⼀下:
ACR122U 是⼀款连机⾮接触式智能卡读写器,可以读写 ISO 14443-4 A 类和 B 类卡、MIFARE®卡、
ISO18092 卡以及 FeliCa 标签。由于符合 PC/SC 标准,它可以与现有的 PC/SC 应⽤相兼容。
作为⾮接触式标签与个⼈电脑的中间设备,ACR122U 通过 USB 端⼝与电脑建⽴连接并执⾏电脑发出 的指令,从⽽实现与⾮接触式标签的通信或者对外围设备(LED 指⽰灯或蜂鸣器)进⾏控制。
具体M1卡的介绍,推荐链接:
M1卡⾥⾯有16(0-15)个扇区,每个扇区包含4个块,0扇区是0-3区块,1扇区是4-7区块,,,以此类推,15扇区就是60-63。
(1)其中0扇区⾥的0区块存储的是⼚商代码,已经固化,不可更改。
(2)每个扇区的块0(除0扇区外)、块1、块2 为数据块,可⽤于存贮数据。数据块可作两种应⽤: ⽤作⼀般的数据保存,可以进⾏读、写操作。
⽤作数据值,可以进⾏初始化值、加值、减值、读值操作。
(3)每个扇区的块3 为控制块,包括了密码A、存取控制、密码B。
这个图是⽤破解⼯具读取出来的M1卡的数据。存储的是16进制的数据。
这是我做的页⾯
这是窗体的代码
1using System;
2using System.Drawing;
3using System.Linq;
4using System.Windows.Forms;
5
6namespace WindowsFormsApplication1
7 {
8public partial class NFCCardForm : Form
9 {
10public NFCCardForm()
11 {
12 InitializeComponent();
13 }
14
15#region全局变量声明
16public int retCode, hContext, hCard, Protocol, ReaderCount, nBytesRet, blockCount, blockNum, ShanQuNum, yuShu; 17public bool connActive = false;
18public byte[] SendBuff = new byte[263];//最多可以放752个
19public byte[] RecvBuff = new byte[263];
20public byte[] SendBuffAll = new byte[263];//全部
21public byte[] RecvBuffAll = new byte[263];
22public byte[] bytes = new byte[263];
23public int SendLen, RecvLen, ReaderLen, ATRLen, dwState, dwActProtocol;
24public int reqType, Aprotocol, dwProtocol, cbPciLength;
25public ModWinsCard.SCARD_IO_REQUEST pioSendRequest;
26string readStr = "";
27public static string writeStr = "";
28bool isReadAll = false;
29#endregion
30
31#region窗体事件
32private void Form1_Load(object sender, EventArgs e)
33 {
34 InitMenu();
35 }
36
37///<summary>
38///读卡器初始化
39///</summary>
40///<param name="sender"></param>
41///<param name="e"></param>
42private void bInit_Click(object sender, EventArgs e)
43 {
44string ReaderList = "" + Convert.ToChar(0);
45int indx;
47string rName = "";
48
49//Establish Context
50 retCode = ModWinsCard.SCardEstablishContext(ModWinsCard.SCARD_SCOPE_USER, 0, 0, ref hContext);
51
52if (retCode != ModWinsCard.SCARD_S_SUCCESS)
53 {
54 displayOut(1, retCode, "");
55return;
56 }
57
58// 2. List PC/SC card readers installed in the system
59
60 retCode = ModWinsCard.SCardListReaders(this.hContext, null, null, ref pcchReaders);
61
62if (retCode != ModWinsCard.SCARD_S_SUCCESS)
63 {
64 displayOut(1, retCode, "");
65return;
66 }
67 EnableButtons();
68byte[] ReadersList = new byte[pcchReaders];
69// Fill reader list
70 retCode = ModWinsCard.SCardListReaders(this.hContext, null, ReadersList, ref pcchReaders);
71if (retCode != ModWinsCard.SCARD_S_SUCCESS)
72 {
73 mMsg.AppendText("SCardListReaders Error: " + ModWinsCard.GetScardErrMsg(retCode));
74return;
75 }
76else
77 {
78 displayOut(0, 0, "");
79 }
80
81 rName = "";
82 indx = 0;
83
84//Convert reader buffer to string
85while (ReadersList[indx] != 0)
86 {
87while (ReadersList[indx] != 0)
88 {
89 rName = rName + (char)ReadersList[indx];
90 indx = indx + 1;
91 }
92//Add reader name to list
93 cbReader.Items.Add(rName);
94 rName = "";
95 indx = indx + 1;
96 }
97
98if (cbReader.Items.Count > 0)
99 {
100 cbReader.SelectedIndex = 0;
101 }
102 }
103
104private void bConnect_Click(object sender, EventArgs e)
105 {
106 retCode = ModWinsCard.SCardConnect(hContext, cbReader.SelectedItem.ToString(), ModWinsCard.SCARD_SHARE_SHARED, 107 ModWinsCard.SCARD_PROTOCOL_T1, ref hCard, ref Protocol);
108
109if (retCode != ModWinsCard.SCARD_S_SUCCESS)
110 {
111 retCode = ModWinsCard.SCardConnect(hContext, cbReader.SelectedItem.ToString(), ModWinsCard.SCARD_SHARE_DIRECT, 1120, ref hCard, ref Protocol);
113if (retCode != ModWinsCard.SCARD_S_SUCCESS)
114 displayOut(1, retCode, "");
115else
116 {
117 displayOut(0, 0, "成功连接到" + cbReader.Text);//Successful connection to
118 }
119 }
120else
121 {
122 displayOut(0, 0, "成功连接到" + cbReader.Text);
123 }
124 GetUID();
125 connActive = true;
126 gbLoadKeys.Enabled = true;
127 gbAuth.Enabled = true;
128 gbBinOps.Enabled = true;
129 groupBox1.Enabled = true;
131 rbKType1.Checked = true;
132 btnClear.Enabled = true;
133 btnRead.Enabled = true;
134 btnWrite.Enabled = true;
135 }
136
137private void bClear_Click(object sender, EventArgs e)
138 {
139 mMsg.Clear();
140 }
141
142private void bReset_Click(object sender, EventArgs e)
143 {
144if (connActive)
145 {
146 retCode = ModWinsCard.SCardDisconnect(hCard, ModWinsCard.SCARD_UNPOWER_CARD);
147 }
148
149 retCode = ModWinsCard.SCardReleaseContext(hCard);
150 InitMenu();
151 }
152
153private void bQuit_Click(object sender, EventArgs e)
154 {
155// terminate the application
156 retCode = ModWinsCard.SCardReleaseContext(hContext);
157 retCode = ModWinsCard.SCardDisconnect(hCard, ModWinsCard.SCARD_UNPOWER_CARD);
158 System.Environment.Exit(0);
159 }
160
161private void bLoadKey_Click(object sender, EventArgs e)
162 {
163byte tmpLong;
164string tmpStr;
165
166if (tKey1.Text == "" | !byte.TryParse(tKey1.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 167 {
168 tKey1.Focus();
169 tKey1.Text = "";
170return;
171 }
172
173if (tKey2.Text == "" | !byte.TryParse(tKey2.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 174 {
175 tKey2.Focus();
176 tKey2.Text = "";
177return;
178 }
179
180if (tKey3.Text == "" | !byte.TryParse(tKey3.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 181 {
182 tKey3.Focus();
183 tKey3.Text = "";
184return;
185 }
186
187if (tKey4.Text == "" | !byte.TryParse(tKey4.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 188 {
189 tKey4.Focus();
190 tKey4.Text = "";
191return;
192 }
193
194if (tKey5.Text == "" | !byte.TryParse(tKey5.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 195 {
196 tKey5.Focus();
197 tKey5.Text = "";
198return;
199 }
200
201if (tKey6.Text == "" | !byte.TryParse(tKey6.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 202 {
203 tKey6.Focus();
204 tKey6.Text = "";
205return;
206 }
207
208 ClearBuffers();
209// Load Authentication Keys command
210 SendBuff[0] = 0xFF; // Class
211 SendBuff[1] = 0x82; // INS
212 SendBuff[2] = 0x00; // P1 : Key Structure
213 SendBuff[3] = byte.Parse(tKeyNum.Text, System.Globalization.NumberStyles.HexNumber);
214 SendBuff[4] = 0x06; // P3 : Lc
215 SendBuff[5] = byte.Parse(tKey1.Text, System.Globalization.NumberStyles.HexNumber); // Key 1 value
216 SendBuff[6] = byte.Parse(tKey2.Text, System.Globalization.NumberStyles.HexNumber); // Key 2 value
217 SendBuff[7] = byte.Parse(tKey3.Text, System.Globalization.NumberStyles.HexNumber); // Key 3 value
218 SendBuff[8] = byte.Parse(tKey4.Text, System.Globalization.NumberStyles.HexNumber); // Key 4 value
219 SendBuff[9] = byte.Parse(tKey5.Text, System.Globalization.NumberStyles.HexNumber); // Key 5 value
220 SendBuff[10] = byte.Parse(tKey6.Text, System.Globalization.NumberStyles.HexNumber); // Key 6 value
221
222 SendLen = 11;
223 RecvLen = 2;
224
225 retCode = SendAPDU(1, false, 0);
226
227if (retCode != ModWinsCard.SCARD_S_SUCCESS)
228 {
229return;
230 }
231else
232 {
233 tmpStr = "";
234for (int indx = RecvLen - 2; indx <= RecvLen - 1; indx++)
235 {
236 tmpStr = tmpStr + "" + string.Format("{0:X2}", RecvBuff[indx]);
237 }
238 }
239if (tmpStr.Trim() != "90 00")
240 {
241 displayOut(4, 0, "载⼊密钥失败!");//Load authentication keys error
242 }
243 }
244
245private void btnAuth_Click(object sender, EventArgs e)
246 {
247int tempInt, indx;
248byte tmpLong;
249string tmpStr;
250
251// Validate input
252if (tBlkNo.Text == "" | !int.TryParse(tBlkNo.Text, out tempInt))
253 {
254 tBlkNo.Focus();
255 tBlkNo.Text = "";
256return;
257 }
258
259if (int.Parse(tBlkNo.Text) > 319)
260 {
261 tBlkNo.Text = "319";
262 }
263
264if (tAuthenKeyNum.Text == "" | !byte.TryParse(tAuthenKeyNum.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 265 {
266 tAuthenKeyNum.Focus();
267 tAuthenKeyNum.Text = "";
268return;
269 }
270else if (int.Parse(tAuthenKeyNum.Text) > 1)
271 {
272 tAuthenKeyNum.Text = "1";
273return;
274 }
275
276 ClearBuffers();
277
278 SendBuff[0] = 0xFF; // Class
279 SendBuff[1] = 0x86; // INS
280 SendBuff[2] = 0x00; // P1
281 SendBuff[3] = 0x00; // P2
282 SendBuff[4] = 0x05; // Lc
283 SendBuff[5] = 0x01; // Byte 1 : Version number
284 SendBuff[6] = 0x00; // Byte 2
285 SendBuff[7] = (byte)int.Parse(tBlkNo.Text); // Byte 3 : Block number
286
m1卡287if (rbKType1.Checked == true)
288 {
289 SendBuff[8] = 0x60;
290 }
291else if (rbKType2.Checked == true)
292 {
293 SendBuff[8] = 0x61;
294 }
295
296 SendBuff[9] = byte.Parse(tAuthenKeyNum.Text, System.Globalization.NumberStyles.HexNumber); // Key 5 value
297