M1卡技术手册(nfc)
AndroidNFCM1卡读写芯片卡读写(CPU卡读写)(RFID读写)
AndroidNFCM1卡读写芯⽚卡读写(CPU卡读写)(RFID读写)权限<uses-featureandroid:name="android.hardware.nfc"android:required="true"/><uses-permission android:name="android.permission.NFC"/>12345<activity android:name=".ReadTextActivity" android:launchMode="singleTop"><intent-filter><action android:name="android.nfc.action.TAG_DISCOVERED"/><action android:name="android.nfc.action.TECH_DISCOVERED" /><data android:mimeType="text/plain"/><category android:name="android.intent.category.DEFAULT"/></intent-filter></activity>12345678初始化在Activity#onCreate()注册,在Activity#onResume()开启前台调度系统,在Activity#onPause退出前台调度。
11 onCreate( initNFC() )private void initNFC() {// 获取nfc适配器,判断设备是否⽀持NFC功能nfcAdapter = NfcAdapter.getDefaultAdapter(this);if (nfcAdapter == null) {shotToast("当前设备不⽀持NFC功能");} else if (!nfcAdapter.isEnabled()) {shotToast("NFC功能未打开,请先开启后重试!");}pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);ndef.addCategory("*/*");// 允许扫描的标签类型mWriteTagFilters = new IntentFilter[]{ndef};mTechLists = new String[][]{new String[]{MifareClassic.class.getName()},new String[]{NfcA.class.getName()}};// 允许扫描的标签类型}1234567891011121314151617182 onResume( )@Overrideprotected void onResume() {super.onResume();//开启前台调度系统nfcAdapter.enableForegroundDispatch(this, pendingIntent, mWriteTagFilters, mTechLists);}1234563 onPause()@Overrideprotected void onPause() {super.onPause();nfcAdapter.disableForegroundDispatch(this);}123454 NFC设备刷卡时触发 onNewIntent(Intent)给伪代码,详细见下⾯3点分解1@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);//当该Activity接收到NFC标签时,运⾏该⽅法if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()) ||NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);1,标签读写Ndef ndef = Ndef.get(tag);//如果ndef为空表⽰不⽀持该格式//可进⾏格式如果格式化失败则不能只能换个⽅式2,M1 扇区读写MifareClassic mfc = MifareClassic.get(tag);//CPU卡时 mfc将为空3,CPU卡读写NfcCpuUtilsnfc = new NfcCpuUtils(IsoDep.get(tag));}}1,标签读写/*** 写标签* @param ndef* @param tag* @param ndefMessage* @return* @throws IOException* @throws FormatException*/private boolean writeMsg(Ndef ndef, Tag tag, NdefMessage ndefMessage) throws IOException, FormatException { try {if (ndef == null) {shotToast("格式化数据开始");//Ndef格式类NdefFormatable format = NdefFormatable.get(tag);format.connect();format.format(ndefMessage);} else {shotToast("写⼊数据开始");//数据的写⼊过程⼀定要有连接操作ndef.connect();ndef.writeNdefMessage(ndefMessage);}return true;} catch (IOException e) {e.printStackTrace();shotToast("IO异常,读写失败");} catch (FormatException e) {e.printStackTrace();shotToast("格式化异常,读写失败");} catch (NullPointerException e) {shotToast("格NullPointerException异常,读写失败");}catch (IllegalStateException e){shotToast("Close other technology first!");}return false;}/*** 读取NFC标签⽂本数据*/private void readNfcTag(Intent intent) {if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())||NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);NdefMessage msgs[] = null;int contentSize = 0;if (rawMsgs != null) {msgs = new NdefMessage[rawMsgs.length];for (int i = 0; i < rawMsgs.length; i++) {msgs[i] = (NdefMessage) rawMsgs[i];contentSize += msgs[i].toByteArray().length;}}try {if (msgs != null) {print(msgs.length+" 长度");NdefRecord record = msgs[0].getRecords()[0];String textRecord = parseTextRecord(record);mTagText += textRecord + "\n\ntext\n" + contentSize + " bytes";print(mTagText);}} catch (Exception e) {}}}12,扇区读写M1扇区默认是没有密码的,但有部分⼈闲不住要把密码改了,因此认证过程要加密码,⼀般认证KeyA就⾏。
M1卡片技术要求
1. 招标要求:
1)卡片
芯片类型Mifare1
容量为不小于1K
外形选用手表式等适合于学生的类型
2)读卡器要求:
"技术参数
工作频率:13.56MHz±7KHz
符合协议:ISO/IEC14443A/B
读取距离:典型标签读写距离10cm以上(与天线和标签有关)
输出功率:200mW
通信接口:串口
工作温度:-25℃~60℃
其他特性:提供完备的接口函数库和演示程序
外形需采用立桩式
3)控制器
读头接口:同读卡器匹配
输入输出:TVS保护,过流,过压,防雷,防反接,防短路联网方式:TCP/IP
存储能力:2万条权限,10万条记录
识别速度:2万条权限时<0.1秒
防撬输入:1路
额定电压:220V AC
额定电流:<0.5A(继电器全部工作,不含读头)
工作温度:-25℃~60℃
其他特征:支持多种开门方式:密码开门、刷卡开门、卡+密码开门、首卡开门、多卡开门、按钮开门、远程开门等支持时段功能:多达256个时段设置,每个时段可设置3个时区
支持多门互锁
支持反潜回
支持消防联动,可外接火警、烟雾传感等信号,5路外部触发输入
支持多种报警,火警、强行闯入、门超时未关报警时联动输出
所有事件记录和报警记录实时主动上传,且可设置是否需要上传
外形规格:340*290*76mm 重量:3kg
外壳材料:镀锌板
颜色:黑色"。
使用ACR122UNFC读卡器对M1卡进行读写操作(可以读写中文)
使⽤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;56namespace WindowsFormsApplication17 {8public partial class NFCCardForm : Form9 {10public NFCCardForm()11 {12 InitializeComponent();13 }1415#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#endregion3031#region窗体事件32private void Form1_Load(object sender, EventArgs e)33 {34 InitMenu();35 }3637///<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 = "";4849//Establish Context50 retCode = ModWinsCard.SCardEstablishContext(ModWinsCard.SCARD_SCOPE_USER, 0, 0, ref hContext);5152if (retCode != ModWinsCard.SCARD_S_SUCCESS)53 {54 displayOut(1, retCode, "");55return;56 }5758// 2. List PC/SC card readers installed in the system5960 retCode = ModWinsCard.SCardListReaders(this.hContext, null, null, ref pcchReaders);6162if (retCode != ModWinsCard.SCARD_S_SUCCESS)63 {64 displayOut(1, retCode, "");65return;66 }67 EnableButtons();68byte[] ReadersList = new byte[pcchReaders];69// Fill reader list70 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 }76else77 {78 displayOut(0, 0, "");79 }8081 rName = "";82 indx = 0;8384//Convert reader buffer to string85while (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 list93 cbReader.Items.Add(rName);94 rName = "";95 indx = indx + 1;96 }9798if (cbReader.Items.Count > 0)99 {100 cbReader.SelectedIndex = 0;101 }102 }103104private 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);108109if (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, "");115else116 {117 displayOut(0, 0, "成功连接到" + cbReader.Text);//Successful connection to118 }119 }120else121 {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 }136137private void bClear_Click(object sender, EventArgs e)138 {139 mMsg.Clear();140 }141142private void bReset_Click(object sender, EventArgs e)143 {144if (connActive)145 {146 retCode = ModWinsCard.SCardDisconnect(hCard, ModWinsCard.SCARD_UNPOWER_CARD);147 }148149 retCode = ModWinsCard.SCardReleaseContext(hCard);150 InitMenu();151 }152153private void bQuit_Click(object sender, EventArgs e)154 {155// terminate the application156 retCode = ModWinsCard.SCardReleaseContext(hContext);157 retCode = ModWinsCard.SCardDisconnect(hCard, ModWinsCard.SCARD_UNPOWER_CARD);158 System.Environment.Exit(0);159 }160161private void bLoadKey_Click(object sender, EventArgs e)162 {163byte tmpLong;164string tmpStr;165166if (tKey1.Text == "" | !byte.TryParse(tKey1.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 167 {168 tKey1.Focus();169 tKey1.Text = "";170return;171 }172173if (tKey2.Text == "" | !byte.TryParse(tKey2.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 174 {175 tKey2.Focus();176 tKey2.Text = "";177return;178 }179180if (tKey3.Text == "" | !byte.TryParse(tKey3.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 181 {182 tKey3.Focus();183 tKey3.Text = "";184return;185 }186187if (tKey4.Text == "" | !byte.TryParse(tKey4.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 188 {189 tKey4.Focus();190 tKey4.Text = "";191return;192 }193194if (tKey5.Text == "" | !byte.TryParse(tKey5.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 195 {196 tKey5.Focus();197 tKey5.Text = "";198return;199 }200201if (tKey6.Text == "" | !byte.TryParse(tKey6.Text, System.Globalization.NumberStyles.HexNumber, null, out tmpLong)) 202 {203 tKey6.Focus();204 tKey6.Text = "";205return;206 }207208 ClearBuffers();209// Load Authentication Keys command210 SendBuff[0] = 0xFF; // Class211 SendBuff[1] = 0x82; // INS212 SendBuff[2] = 0x00; // P1 : Key Structure213 SendBuff[3] = byte.Parse(tKeyNum.Text, System.Globalization.NumberStyles.HexNumber);214 SendBuff[4] = 0x06; // P3 : Lc215 SendBuff[5] = byte.Parse(tKey1.Text, System.Globalization.NumberStyles.HexNumber); // Key 1 value216 SendBuff[6] = byte.Parse(tKey2.Text, System.Globalization.NumberStyles.HexNumber); // Key 2 value217 SendBuff[7] = byte.Parse(tKey3.Text, System.Globalization.NumberStyles.HexNumber); // Key 3 value218 SendBuff[8] = byte.Parse(tKey4.Text, System.Globalization.NumberStyles.HexNumber); // Key 4 value219 SendBuff[9] = byte.Parse(tKey5.Text, System.Globalization.NumberStyles.HexNumber); // Key 5 value220 SendBuff[10] = byte.Parse(tKey6.Text, System.Globalization.NumberStyles.HexNumber); // Key 6 value221222 SendLen = 11;223 RecvLen = 2;224225 retCode = SendAPDU(1, false, 0);226227if (retCode != ModWinsCard.SCARD_S_SUCCESS)228 {229return;230 }231else232 {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 error242 }243 }244245private void btnAuth_Click(object sender, EventArgs e)246 {247int tempInt, indx;248byte tmpLong;249string tmpStr;250251// Validate input252if (tBlkNo.Text == "" | !int.TryParse(tBlkNo.Text, out tempInt))253 {254 tBlkNo.Focus();255 tBlkNo.Text = "";256return;257 }258259if (int.Parse(tBlkNo.Text) > 319)260 {261 tBlkNo.Text = "319";262 }263264if (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 }275276 ClearBuffers();277278 SendBuff[0] = 0xFF; // Class279 SendBuff[1] = 0x86; // INS280 SendBuff[2] = 0x00; // P1281 SendBuff[3] = 0x00; // P2282 SendBuff[4] = 0x05; // Lc283 SendBuff[5] = 0x01; // Byte 1 : Version number284 SendBuff[6] = 0x00; // Byte 2285 SendBuff[7] = (byte)int.Parse(tBlkNo.Text); // Byte 3 : Block number286287if (rbKType1.Checked == true)288 {289 SendBuff[8] = 0x60;290 }291else if (rbKType2.Checked == true)292 {293 SendBuff[8] = 0x61;294 }295296 SendBuff[9] = byte.Parse(tAuthenKeyNum.Text, System.Globalization.NumberStyles.HexNumber); // Key 5 value297298 SendLen = 10;299 RecvLen = 2;300301 retCode = SendAPDU(1, false, 0);302303if (retCode != ModWinsCard.SCARD_S_SUCCESS)304 {305return;306 }307else308 {309 tmpStr = "";310for (indx = 0; indx <= RecvLen - 1; indx++)311 {312 tmpStr = tmpStr + "" + string.Format("{0:X2}", RecvBuff[indx]); 313 }314 }315if (tmpStr.Trim() == "90 00")316 {317 displayOut(0, 0, "验证成功!");//Authentication success318 }319else320 {321 displayOut(4, 0, "验证失败!");//Authentication failed322 }323 }324325private void bBinRead_Click(object sender, EventArgs e)326 {327string tmpStr;328int indx;329330// Validate Inputs331 tBinData.Text = "";332333if (tBinBlk.Text == "")334 {335 tBinBlk.Focus();336return;337 }338339if (int.Parse(tBinBlk.Text) > 319)340 {341 tBinBlk.Text = "319";342return;343 }344345if (tBinLen.Text == "")346 {347 tBinLen.Focus();348return;349 }350351 ClearBuffers();352 SendBuff[0] = 0xFF;353 SendBuff[1] = 0xB0;354 SendBuff[2] = 0x00;355 SendBuff[3] = (byte)int.Parse(tBinBlk.Text);356 SendBuff[4] = (byte)int.Parse(tBinLen.Text);357358 SendLen = 5;359 RecvLen = SendBuff[4] + 2;360361 retCode = SendAPDU(1, false, 0);362363if (retCode != ModWinsCard.SCARD_S_SUCCESS)364 {365return;366 }367else368 {369 tmpStr = "";370for (indx = RecvLen - 2; indx <= RecvLen - 1; indx++)371 {372 tmpStr = tmpStr + "" + string.Format("{0:X2}", RecvBuff[indx]); 373 }374 }375if (tmpStr.Trim() == "90 00")376 {377 tmpStr = "";378 tmpStr = System.Text.Encoding.Default.GetString(RecvBuff);379byte[] c = new byte[263];380if (tmpStr.Contains('?'))381 {382if (IsBase64String(tmpStr.Split('?')[0]))383 {384 c = Convert.FromBase64String(tmpStr.Split('?')[0]);385 tmpStr = System.Text.Encoding.Default.GetString(c);386 }387 }388else389 {390if (IsBase64String(tmpStr))391 {392 c = Convert.FromBase64String(tmpStr);393 tmpStr = System.Text.Encoding.Default.GetString(c);394 }395 }396 tBinData.Text = tmpStr;397 displayOut(3, 0, tmpStr);398 }399else400 {401 displayOut(4, 0, "读取块失败!");//Read block error402 }403 }404405private void bBinUpd_Click(object sender, EventArgs e)406 {407string tmpStr;408int indx, tempInt;409410if (tBinBlk.Text == "" | !int.TryParse(tBinBlk.Text, out tempInt))411 {412 tBinBlk.Focus();413 tBinBlk.Text = "";414return;415 }416417if (int.Parse(tBinBlk.Text) > 319)418 {419 tBinBlk.Text = "319";420return;421 }422423if (tBinLen.Text == "" | !int.TryParse(tBinLen.Text, out tempInt))424 {425 tBinLen.Focus();426 tBinLen.Text = "";427return;428 }429430if (tBinData.Text == "")431 {432 tBinData.Focus();433return;434 }435436 tmpStr = tBinData.Text;437byte[] b = System.Text.Encoding.Default.GetBytes(tmpStr);438//转成 Base64 形式的 System.String439 tmpStr = Convert.ToBase64String(b);440//将base64转成字符数组然后写⼊卡中441 bytes = System.Text.Encoding.Default.GetBytes(tmpStr);442if (bytes.Length > 16)443 {444 MessageBox.Show("写⼊的数据长度超过16,请重新输⼊");445return;446 }447 ClearBuffers();448 SendBuff[0] = 0xFF; // CLA449 SendBuff[1] = 0xD6; // INS450 SendBuff[2] = 0x00; // P1451 SendBuff[3] = (byte)int.Parse(tBinBlk.Text); // P2 : Starting Block No.452 SendBuff[4] = (byte)bytes.Length; //(byte)int.Parse(tBinLen.Text); // P3 : Data length 453454for (indx = 0; indx <= bytes.Length - 1; indx++)455 {456 SendBuff[indx + 5] = bytes[indx];457 }458 SendLen = SendBuff[4] + 5;//459 RecvLen = 0x02;460461 retCode = SendAPDU(2, false, 0);462463if (retCode != ModWinsCard.SCARD_S_SUCCESS)464 {465return;468 {469 tmpStr = "";470for (indx = 0; indx <= RecvLen - 1; indx++)471 {472 tmpStr = tmpStr + "" + string.Format("{0:X2}", RecvBuff[indx]); 473 }474 }475if (tmpStr.Trim() == "90 00")476 {477 tBinData.Text = "";478 }479else480 {481 displayOut(2, 0, tmpStr.Trim());//""482 }483 }484485private void btnRead_Click(object sender, EventArgs e)486 {487string readData = readStr;488 AuthAllBootSector(1);489if (readStr == null)490return;491492if (IsBase64String(readStr.Split('?')[0]))493 {494byte[] c = Convert.FromBase64String(readStr);495 readData = System.Text.Encoding.Default.GetString(c);496if (readData.Contains("结"))497 readData = readData.Substring(0, readData.IndexOf("结"));498 }499 readStr = null;500 displayOut(3, 0, readData);501502 }503504private void btnWrite_Click(object sender, EventArgs e)505 {506 AuthAllBootSector(2);507 blockCount = 0;508 }509510///<summary>511///当⽂本框⾥的值发⽣改变时,动态显⽰出写⼊数据的长度512///</summary>513///<param name="sender"></param>514///<param name="e"></param>515private void tBinData_TextChanged(object sender, EventArgs e)516 {517string tmpStr = tBinData.Text;518byte[] b = System.Text.Encoding.Default.GetBytes(tmpStr);519//转成 Base64 形式的 System.String520 tmpStr = Convert.ToBase64String(b);521//将base64转成字节数组然后写⼊卡中522 bytes = System.Text.Encoding.Default.GetBytes(tmpStr);523 lblWriteLength.Text = bytes.Length.ToString();524 }525526///<summary>527///在写⼊新的内容时,先将卡⾥的原数据清空528///</summary>529///<param name="sender"></param>530///<param name="e"></param>531private void btnClear_Click(object sender, EventArgs e)532 {533int result;534for (int index = 0; index <= 63; index += 4)//验证535 {536 ClearBuffers();537 SendBuff[0] = 0xFF; // Class538 SendBuff[1] = 0x86; // INS539 SendBuff[2] = 0x00; // P1540 SendBuff[3] = 0x00; // P2541 SendBuff[4] = 0x05; // Lc542 SendBuff[5] = 0x01; // Byte 1 : Version number 543 SendBuff[6] = 0x00; // Byte 2544 SendBuff[7] = (byte)index;//区块 // Byte 3 : Block number 545546 result = PartAuthBlock(0, index);547if (result == 0)548break;549 }552553#region⾃定义⽅法554private void InitMenu()555 {556 connActive = false;557 cbReader.Text = "";558 cbReader.Items.Clear();559 mMsg.Text = "";560 tKeyNum.SelectedIndex = 0;561 tAuthenKeyNum.SelectedIndex = 0;562 bInit.Enabled = true;563 bConnect.Enabled = false;564 bClear.Enabled = false;565 displayOut(0, 0, "程序准备就绪");//Program ready566 bReset.Enabled = false;567 gbLoadKeys.Enabled = false;568 gbAuth.Enabled = false;569 gbBinOps.Enabled = false;570 groupBox1.Enabled = false;571 btnClear.Enabled = false;572 btnRead.Enabled = false;573 btnWrite.Enabled = false;574 }575576private void displayOut(int errType, int retVal, string PrintText) 577 {578switch (errType)579 {580case0:581 mMsg.SelectionColor = Color.Green;582break;583case1:584 mMsg.SelectionColor = Color.Red;585 PrintText = ModWinsCard.GetScardErrMsg(retVal);586break;587case2:588 mMsg.SelectionColor = Color.Black;589 PrintText = "<" + PrintText;590break;591case3:592 mMsg.SelectionColor = Color.Black;593 PrintText = ">" + PrintText;594break;595case4:596break;597 }598 mMsg.AppendText(PrintText);599 mMsg.AppendText("\n");600 mMsg.SelectionColor = Color.Black;601 mMsg.Focus();602 }603604private void EnableButtons()605 {606 bInit.Enabled = false;607 bConnect.Enabled = true;608 bClear.Enabled = true;609 bReset.Enabled = true;610 }611612private void ClearBuffers()613 {614long indx;615616for (indx = 0; indx <= 262; indx++)617 {618 RecvBuff[indx] = 0;619 SendBuff[indx] = 0;620 RecvBuffAll[indx] = 0;621 SendBuffAll[indx] = 0;622 }623 }624625//private static byte[] StringToByteSequence(string sourceString) 626//{627// int i = 0, n = 0;628// int j = (sourceString.Length) / 2;629630// byte[] a = new byte[j];631// for (i = 0, n = 0; n < j; i += 2, n++)632// {633// a[n] = Convert.ToByte(sourceString.Substring(i, 2), 16);636//}637638///<summary>639///640///</summary>641///<param name="handleFlag">是否是更新操作</param>642///<param name="isReadOrWriteAll">是不是全部读取或写⼊</param>643///<returns></returns>644public int SendAPDU(int handleFlag, bool isReadOrWriteAll, int dataLength)645 {646int indx;647string tmpStr;648649 pioSendRequest.dwProtocol = Aprotocol;650 pioSendRequest.cbPciLength = 8;651652// Display Apdu In653 tmpStr = "";654if (handleFlag == 2)//更新655 {656if (isReadOrWriteAll)657 {658for (indx = 0; indx <= 4; indx++)659 {660 tmpStr = tmpStr + "" + string.Format("{0:X2}", SendBuffAll[indx]);//更新的APDU命令661 }662for (int i = 0; i <= SendLen - 6; i++)663 {664 SendBuffAll[i + 5] = bytes[i + dataLength];665 }666 SendLen = 21;667 }668else669 {670for (indx = 0; indx <= 4; indx++)671 {672 tmpStr = tmpStr + "" + string.Format("{0:X2}", SendBuff[indx]);//更新的APDU命令673 }674for (int i = 0; i <= SendLen - 6; i++)675 {676 SendBuff[i + 5] = bytes[i];677 }678 }679 }680else if (handleFlag == 1)//读取681 {682if (isReadOrWriteAll)//全部683 {684for (indx = 0; indx <= SendLen - 1; indx++)685 {686 tmpStr = tmpStr + "" + string.Format("{0:X2}", SendBuffAll[indx]);687 }688 }689else690 {691for (indx = 0; indx <= SendLen - 1; indx++)692 {693 tmpStr = tmpStr + "" + string.Format("{0:X2}", SendBuff[indx]);694 }695 }696 }697else if (handleFlag == 0)//清空698 {699for (indx = 0; indx <= 4; indx++)700 {701 tmpStr = tmpStr + "" + string.Format("{0:X2}", SendBuffAll[indx]);//更新的APDU命令702 }703for (int i = 0; i <= SendLen - 6; i++)704 {705 SendBuffAll[i + 5] = 0x00;706 }707 }708709 displayOut(2, 0, tmpStr);710if (!isReadOrWriteAll)711 retCode = ModWinsCard.SCardTransmit(hCard, ref pioSendRequest, ref SendBuff[0], SendLen, ref pioSendRequest, ref RecvBuff[0], ref RecvLen);712else713 retCode = ModWinsCard.SCardTransmit(hCard, ref pioSendRequest, ref SendBuffAll[0], SendLen, ref pioSendRequest, ref RecvBuffAll[0], ref RecvLen); 714715if (retCode != ModWinsCard.SCARD_S_SUCCESS)716 {717 displayOut(1, retCode, "");718return retCode;719 }720721 tmpStr = "";722if (isReadOrWriteAll)723 {724for (indx = 0; indx <= RecvLen - 1; indx++)725 {726 tmpStr = tmpStr + "" + string.Format("{0:X2}", RecvBuffAll[indx]);727 }728 }729else730 {731for (indx = 0; indx <= RecvLen - 1; indx++)732 {733 tmpStr = tmpStr + "" + string.Format("{0:X2}", RecvBuff[indx]);734 }735 }736 displayOut(3, 0, tmpStr);737return retCode;738 }739740#region GetUID()741///<summary>742///获取UID743///</summary>744private void GetUID()745 {746// Get the firmaware version of the reader747string tmpStr;748int intIndx;749 ClearBuffers();750751#region GetFirmware APDU752//SendBuff[0] = 0xFF;753//SendBuff[1] = 0x00;754//SendBuff[2] = 0x48;755//SendBuff[3] = 0x00;756//SendBuff[4] = 0x00;757//SendLen = 5;758//RecvLen = 10;759#endregion760761 SendBuff[0] = 0xFF;762 SendBuff[1] = 0xCA;763 SendBuff[2] = 0x00;764 SendBuff[3] = 0x00;765 SendBuff[4] = 0x00;766 SendLen = 5;767 RecvLen = 10;768 retCode = SendAPDU(1, false, 0);769if (retCode != ModWinsCard.SCARD_S_SUCCESS)770return;771772// Interpret firmware data773//tmpStr = "Firmware Version(版本): ";774 tmpStr = "UID: ";775for (intIndx = 0; intIndx <= RecvLen - 3; intIndx++)776 {777 tmpStr = tmpStr + string.Format("{0:X2}", RecvBuff[intIndx]);778 }779 displayOut(3, 0, tmpStr);780 }781#endregion782783///<summary>784///验证所有区块785///</summary>786///<param name="handleFlag">处理操作的标志handleFlag 0清空,1读取,2写⼊</param> 787private void AuthAllBootSector(int handleFlag)788 {789int result;790791if (handleFlag == 2)792 {793string data = writeStr;//获取要写⼊的字符串794byte[] b = System.Text.Encoding.Default.GetBytes(data);795//转成 Base64 形式的 System.String796 data = Convert.ToBase64String(b);797 bytes = System.Text.Encoding.Default.GetBytes(data);798if (bytes.Length % 16 != 0)799 {800 b = null;801string endSign = "结结结结结结结";802//for (int i = 0; i < (bytes.Length % 16); i++)803//{804//endSign = "结结结结结结结"; //写⼊的数据不够填充满16位,最后的base64容易混乱,所以加个汉字,填满16位 805//}806string str = writeStr + endSign;807 b = System.Text.Encoding.Default.GetBytes(str);808 data = "";809 data = Convert.ToBase64String(b);810 }811812//将base64转成16进制然后写⼊卡中813 bytes = System.Text.Encoding.Default.GetBytes(data);814//写⼊的数据需要的区块数量815 blockNum = (bytes.Length % 16 == 0 ? (bytes.Length / 16) : (bytes.Length / 16 + 1));816//需要验证的扇区的数量,把有两个数据块的0扇区加上817 ShanQuNum = (blockNum - 2) % 3 == 0 ? (blockNum - 2) / 3 + 1 : (blockNum - 2) / 3 + 2;818//获取最后⼀个扇区的写⼊的块的数量,yushu==0,则正好写满当前验证块(3块数据块);819//yushu==1,则写⼊当前验证块;yushu==2,则写⼊当前验证块+1820 yuShu = (blockNum - 2) % 3;821for (int i = 0; i < 4 * ShanQuNum; i += 4) //验证块822 {823 ClearBuffers();824 SendBuff[0] = 0xFF; // Class825 SendBuff[1] = 0x86; // INS826 SendBuff[2] = 0x00; // P1827 SendBuff[3] = 0x00; // P2828 SendBuff[4] = 0x05; // Lc829 SendBuff[5] = 0x01; // Byte 1 : Version number830 SendBuff[6] = 0x00; // Byte 2831 SendBuff[7] = (byte)i; // Byte 3 : Block number832833 result = PartAuthBlock(handleFlag, i);834if (result == 0)835break;836 }837 }838else if (handleFlag == 1)839 {840for (int index = 0; index <= 63; index += 4)//验证841 {842 ClearBuffers();843 SendBuff[0] = 0xFF; // Class844 SendBuff[1] = 0x86; // INS845 SendBuff[2] = 0x00; // P1846 SendBuff[3] = 0x00; // P2847 SendBuff[4] = 0x05; // Lc848 SendBuff[5] = 0x01; // Byte 1 : Version number849 SendBuff[6] = 0x00; // Byte 2850 SendBuff[7] = (byte)index;//块 // Byte 3 : Block number851852 result = PartAuthBlock(handleFlag, index);853if (result == 0)854break;855 }856 }857 }858859///<summary>860///在读取或写⼊操作前需要验证区块861///</summary>862///<param name="handleFlag">是否为写⼊、更新操作</param>863///<param name="index">验证的区块号</param>864///<returns></returns>865private int PartAuthBlock(int handleFlag, int index)866 {867int indx;868string tmpStr;869if (rbKType1.Checked == true)870 {871 SendBuff[8] = 0x60;//keyA872 }873else if (rbKType2.Checked == true)874 {875 SendBuff[8] = 0x61;//keyB876 }877878 SendBuff[9] = byte.Parse(tAuthenKeyNum.Text, System.Globalization.NumberStyles.HexNumber); // Key 5 value 879880 SendLen = 10;881 RecvLen = 2;882883 retCode = SendAPDU(1, false, 0);884885if (retCode != ModWinsCard.SCARD_S_SUCCESS)886 {887return2;888 }889else890 {891 tmpStr = "";892for (indx = 0; indx <= RecvLen - 1; indx++)893 {894 tmpStr = tmpStr + "" + string.Format("{0:X2}", RecvBuff[indx]);895 }896 }897if (tmpStr.Trim() == "90 00")898 {899 displayOut(0, 0, "验证成功!");//Authentication success900if (handleFlag == 0)//清空901 {902if (index == 0)903 {904 index += 1;//从块1开始写⼊905for (int i = index; i <= 2; i++)906 {907 AllBlockClear(i);908 }909 }910else911 {912for (int i = index; i <= index + 2; i++)913 {914 AllBlockClear(i);915 }916 }917 }918else if (handleFlag == 1)//读取919 {920 ReadAllBlock(index);921 }922else if (handleFlag == 2)//写⼊923 {924bool isLastBlock = false;925if (index == 0)926 {927 index += 1;//从块1开始写⼊928if ((index + 1) < blockNum)929 {930for (int i = index; i <= index + 1; i++)931 {932 AllBlockWrite(i, false);//这⾥写每个块的写⼊循环933 }934 }935else936 {937for (int i = index; i <= blockNum; i++)938 {939if (i == blockNum)940 isLastBlock = true;941 AllBlockWrite(i, isLastBlock);//这⾥写每个块的写⼊循环942 }943 }944 }945else946 {947int temp = yuShu == 0 ? (ShanQuNum-1) * 4 : (ShanQuNum - 2) * 4; 948if (index < (ShanQuNum - 1) * 4)949 {950for (int i = index; i < index + 3; i++)951 {952 AllBlockWrite(i, false);//这⾥写每个块的写⼊循环953 }954 }955else956 {957if (yuShu == 0 && index == (ShanQuNum - 1) * 4)958 {959for (int i = index; i < index + 3; i++)960 {961if (i == index + 2)962 isLastBlock = true;963 AllBlockWrite(i, isLastBlock);//这⾥写每个块的写⼊循环964 }965 }966else967 {968for (int i = index; i <= index + yuShu - 1; i++)969 {。
标准M1卡逻辑加密IC卡门禁读卡器软硬件说明
Mifare卡门禁读卡器产品介绍修订历史目录1.产品概述 (1)1.1性能指标 (1)1.2实物照片 (2)1.3选型指南 (3)2.使用方法 (4)2.1读卡器端口说明 (4)2.2使用方法 (4)2.3安装注意事项 (5)2.4常见故障分析 (5)3.定制开发 (7)4.技术支持 (8)5.联系方式 (9)5.1联系方式 (9)1.产品概述1.1性能指标●【产品型号】:R5-M1/R6- M1/R6K- M1●【支持卡片】:Mifare S50/S70卡的扇区加密数据读取;●【处理芯片】:专业读卡芯片,速度更快更稳定;●【输出格式】:韦根(Wiegand)输出;●【韦根位数】:标准韦根18~130可配置;●【读卡距离】:0~7cm;●【通信距离】:读卡器到控制器通信距离大可达100米(RVVP 8*0.3);●【读卡时间】:<200ms;●【LED指示】:红、绿双色条形状态指示灯;●【外壳顔色】:黑色;●【外壳体积】:86×45×15mm /86×86×15mm●【工作电源】:9~18V●【工作电流】:<100mA(普通)●【工作温度】:-20~85℃1.2实物照片1.3选型指南2.使用方法2.1读卡器端口说明R5-M1 /R6- M1 /R6K- M1门禁读卡器端口说明如1所示:表1门禁读卡器接口说明2.2使用方法1.读卡器上电读卡器上电时蜂鸣器会短鸣一声,表示门禁读卡器系统可正常启用运行。
2.工作模式有效用户CPU卡刷卡时,门禁读卡器蜂鸣器会短鸣一声,绿色LED灯会闪烁一下(可设置开门状态),同时通过韦根方式上传所读的数据。
无效CPU卡刷卡时(未经初始化或密钥不正确),读卡器可自动识别为非法卡,蜂鸣器和LED 灯均不会做出任何反应。
3.蜂鸣器、指示灯受控指示蜂鸣器和指示灯受门禁控制器控制,当对以上信号线输入低电平时蜂鸣器会鸣叫及指示灯会亮绿色。
RFID之M1卡数据资料
0x01契机一直没有机会也没下定决心认真的去研究某个安全领域,很早之前就看到好多人研究RFID,一直很憧憬那片天空,趁着老大给机会,决定选这个方向作为个人业余努力的方向。
差不多四天前入手了ACR122U,决定拿自己母校的餐厅饭卡练手。
ACR122U的使用很简单,只要安装上驱动,使用M1卡服务程序就可以很快破解,破解完成后查看其生成的dump文件,找到加密扇区的密码,将密码导入到MCT (Mifare Classic Tool),剩下的就可以完全使用MCT 完成了,个人很怀疑破解过程是否完全可以通过手机(支持NFC)APP完成。
ACR122U的详细使用过程可以参考:RFID安全之某学校水卡破解,本文主要介绍目前M1卡中的数据分析和M1卡安全防护方案。
0x02背景知识了解M1卡的结构可以知道M1卡共16个扇区,编号从0到15,每个扇区配备了从0到3共4个段,每个段可以保存16字节的内容。
0x03数据分析阅读《RFID安全之某学校水卡破解》可以发现该学校的水卡中数据存储比较简单,按照作者的分析,4号扇区的1、2号数据段(编号从0开始)存储了水卡余额,将已知的余额32.31,换算为分为3231,再转为10进制为C9F,即00000C9F,而0C9F取反为FFFFF360,这时比较下4号扇区的值,很容易发现规律:前四个字节不取反倒序(9F0C0000)存储余额,接下来四个字节取反倒序(60F3FFFF)存储余额,再接下来四个字节不取反倒序(9F0C0000)存储余额。
上面提到的“倒序”,可以结合计算机数据存储方式来理解:如下图所示,变量a存储的数据对应的16进制为0A112233,变量b存储的数据对应的16进制为0B445566。
这样就很明显了,5634120A,就是变量a所代表的数据的十六进制0A123456的倒序。
作为入门教程,个人认为《RFID安全之某学校水卡破解》是非常不错的。
看完这个教程,并实践结束后,我停下来思考这样一个问题:M1卡的密码破解是傻瓜式的,当然也有文章介绍破解原理,但是作为门外汉,目前我还不是特别关心,我只想找到那种破解成功,可以修改金额的快感!那么在整个M1卡的破解过程中,我自己到底起了什么作用?答案是卡片的数据分析。
M1卡技术知识详解
M1卡技术知识详解1.什么是MIFARE?MIFARE技术是一种13.56 MHz非接触式技术,归Philips Electronics 所有。
该公司并不生产智能卡或读卡器,而是生产智能卡和读卡器的芯片,并在公开市场上销售这些芯片。
智能卡和读卡器制造商(例如 HID)使用这种技术生产独特的产品,供最终用户使用。
MIFARE通常被看作是一种“智能卡”技术。
这种看法的依据是MIFARE具有读/写智能卡的能力。
事实上,MIFARE只是一张内存卡(与处理器卡对照)而已。
最初开发MIFARE非接触式智能卡和MIFARE 读卡器/写卡器,是为了处理公共交通系统的付款交易。
由于MIFARE的读取距离较短,因此以前它仅适合执行一些增值/减值功能。
虽然接触式智能卡也能完成这类任务,但非接触式智能卡使用起来更迅速、方便,几乎不需要维护读卡器,智能卡也不会磨损。
迄今为止,MIFARE在非接触式门禁应用中的使用面很有限。
这是因为,与感应(125kHz技术)产品相比,MIFARE 产品的读取距离比较短。
2.HID MIFARE 产品有何独特之处?对于要求格式化韦根输出的门禁系统OEM来说,HID能够提供根据需要特定配置的读卡器和智能卡,这便是HID的独特之处。
HID能将OEM的数据编制到M1卡的某个扇区中,还能用125kHz感应卡当前可使用的任何地址号、格式和编号序列对感应卡进行编制。
HID 读卡器能在M1卡上找到 HID OEM 数据,并通过韦根端口输出这些数据。
HID的做法与大多数其它 MIFARE 读卡器供应商不同。
这些供应商满足韦根要求的方法是先获得 Philips 随机芯片的 ID,然后将其转换成 32 位韦根输出,或者将其截成26位韦根输出。
由于这些输出基于随机编号,因此既不能提供连续的编号序列,也不能提供指定的编号范围。
另外,将较长的随机编号截去一段(称作截短)还会带来编号重复(称作混淆)的风险。
3.MIFARE 非接触式智能读卡器的读取距离通常是多少?MIFARE 非接触式智能读卡器的读取距离通常是1.0"到3.9"(即2.5到10cm)。
m1卡 工作原理
m1卡工作原理M1卡工作原理1. M1卡简介M1卡,是一种广泛应用于各种领域的智能卡片。
它采用了非接触式射频识别技术,主要用于身份验证、门禁控制、交通支付等领域。
2. 射频识别原理射频识别(RFID)是一种无线通信技术,通过射频信号实现对物体的识别和数据传输。
M1卡就是基于射频识别技术实现的一种智能卡片。
3. M1卡的内部结构M1卡内部包含一块射频芯片和一块储存芯片。
射频芯片用于接收和发送射频信号,实现与读卡器之间的通信;储存芯片用于存储卡片的数据信息。
4. M1卡的工作模式M1卡具有两种工作模式:被动模式和主动模式。
被动模式在被动模式下,M1卡会等待读卡器发射的射频信号来供电。
当读卡器发射射频信号时,M1卡接收并解码该信号,然后将卡片存储的数据信息发送给读卡器。
主动模式在主动模式下,M1卡可以自己发射射频信号。
通过发射特定的射频信号,M1卡可以与读卡器进行通信,并传输存储在卡片中的数据信息。
5. M1卡的数据存储M1卡的储存芯片将数据存储在一系列的块中。
每个块可以存储特定数量的字节数据。
块的数量和每个块的容量可以根据卡片的类型而有所不同。
6. M1卡的通信协议M1卡与读卡器之间的通信采用特定的通信协议。
常见的通信协议有ISO/IEC 14443和ISO/IEC 15693等。
通信协议规定了卡片和读卡器之间的数据传输格式和操作指令。
7. M1卡的应用领域M1卡广泛应用于各个领域,包括门禁控制、交通支付、园区管理等。
通过读卡器与M1卡的射频通信,可以实现身份验证、进出控制、支付扣款等功能。
8. M1卡的安全性M1卡采用了多种安全机制来确保数据的安全性。
例如,卡片和读卡器之间的通信会进行加密,防止数据泄露;卡片中的数据可以进行读写权限控制,防止未经授权的访问。
以上就是M1卡的工作原理的简要介绍。
通过射频识别技术、内部结构、工作模式、数据存储、通信协议、应用领域和安全性等方面的解析,我们对M1卡有了更深入的了解。
M1卡技术参数
芯片类型:
Philips Mifare 1 IC S50
存储容量:
8Kbit,16个分区,每分区两组密码
工作频率:
13.56 MHz
通讯速率:
106KBoud
读写距离:
2.5~10cm
读写时间:
1~2ms
工作温度:
-20℃~55℃
擦写寿命:
>100,000次
数据保存:
>10年
外形尺寸:
ISO标准卡85.6x54x0.82
封装材料:
PVC、PET、PETG、0.13mm铜线
封装工艺:
超声波自动植线/自动碰焊
执行标准:
ISO14443A
由深圳市联合智能卡有公司提供
M1卡技术参数
M1卡是菲利浦下属子公司恩智浦出品的芯片缩写,全称为NXP Mifare1系列,常用的有S50及S70两种型号,目前都有国产芯片与其兼容,利用PVC封装M1芯片、感应天线,然后压制成型后而制作的卡即是智能卡行业所说的M1卡,属于非接触式IC卡。非接触式IC卡又称射频卡,成功地解决了无源(卡中无电源)和免接触这一难题,是电子器件领域的一大突破。这大大减少人们排队的时间,提高企业的服务质量和人们的财产安全性。主要用于公交、轮渡、地铁的自动收费系统,也应用在门禁管理、身份证明和电子钱包。
Mifare1技术说明(M1卡说明文档)Word版
Mifare 1非接触IC卡技术说明1 特性1.1 MIFARE RF 接口 (ISO/IEC 14443 A)•非接触数据传输并提供能源(不需电池)•工作距离:可达100mm (取决于天线尺寸结构)•工作频率:13.56 MHz•快速数据传输:106 kbit/s•高度数据完整性保护:16 Bit CRC,奇偶校验,位编码,位计数•真正的防冲突•典型票务交易: < 100 ms (包括备份管理)1.2 EEPROM• 1 Kbyte,分为16个区,每区4个块,每块16字节。
•用户可定义内存块的读写条件•数据耐久性10年•写入耐久性100.000次1.3 安全性•相互三轮认证(ISO/IEC DIS9798-2)•带重现攻击保护的射频通道数据加密•每区(每应用)两个密钥,支持密钥分级的多应用场合•每卡一个唯一序列号•在运输过程中以传输密钥保护对EEPROM的访问权2 概述MIFARE MF1是符合ISO/IEC 14443A的非接触智能卡。
其通讯层(MIFARE RF 接口)符合ISO/IEC 14443A标准的第2和第3部分。
其安全层支持域检验的CRYPTO1数据流加密。
2.1 非接触能源和数据传递在MIFARE卡中,芯片连接到一个几匝的天线线圈上,并嵌入塑料中,形成了一个无源的非接触卡。
不需要电池。
当卡接近读写器天线时,高速的RF通讯接口将以106 kBit/s 的速率传输数据。
卡4匝线圈读卡器嵌入的芯片模块天线能量数据2.2 防冲突智能的防冲突功能可以同时操作读写范围内的多张卡。
防冲突算法逐一选定每张卡,保证与选定的卡执行交易,不会导致与读写范围内其他卡的数据冲突。
2.3 用户便捷性MIFARE 是针对用户便捷性优化的。
例如,高速数据传输使得完整的票务交易在不到100 ms 内处理完毕。
因此用户不必在读写器天线处停留,形成高的通过率,减少了公共汽车的登车时间。
在交易时,MIFARE 卡可以留在钱包里,甚至钱包里有硬币也不受影响。
Mifare1技术说明(M1卡说明文档)资料
M i f a r e1技术说明(M1卡说明文档)Mifare 1非接触IC卡技术说明1 特性1.1 MIFARE RF 接口 (ISO/IEC 14443 A)•非接触数据传输并提供能源(不需电池)•工作距离:可达100mm (取决于天线尺寸结构)•工作频率:13.56 MHz• 快速数据传输:106 kbit/s•高度数据完整性保护:16 Bit CRC,奇偶校验,位编码,位计数•真正的防冲突•典型票务交易: < 100 ms (包括备份管理)1.2 EEPROM• 1 Kbyte,分为16个区,每区4个块,每块16字节。
•用户可定义内存块的读写条件•数据耐久性10年•写入耐久性100.000次1.3 安全性•相互三轮认证(ISO/IEC DIS9798-2)•带重现攻击保护的射频通道数据加密•每区(每应用)两个密钥,支持密钥分级的多应用场合•每卡一个唯一序列号•在运输过程中以传输密钥保护对EEPROM的访问权2 概述MIFARE MF1是符合ISO/IEC 14443A的非接触智能卡。
其通讯层(MIFARE RF 接口)符合ISO/IEC 14443A标准的第2和第3部分。
其安全层支持域检验的CRYPTO1数据流加密。
2.1 非接触能源和数据传递在MIFARE卡中,芯片连接到一个几匝的天线线圈上,并嵌入塑料中,形成了一个无源的非接触卡。
不需要电池。
当卡接近读写器天线时,高速的RF通讯接口将以106 kBit/s 的速率传输数据。
卡4匝线圈读卡器嵌入的芯片模块天线能量数据2.2 防冲突智能的防冲突功能可以同时操作读写范围内的多张卡。
防冲突算法逐一选定每张卡,保证与选定的卡执行交易,不会导致与读写范围内其他卡的数据冲突。
2.3 用户便捷性MIFARE是针对用户便捷性优化的。
例如,高速数据传输使得完整的票务交易在不到100 ms内处理完毕。
因此用户不必在读写器天线处停留,形成高的通过率,减少了公共汽车的登车时间。
m1卡 工作原理
m1卡工作原理M1卡是一种近场通信技术(NFC)卡片,广泛应用于支付、门禁、地铁刷卡等领域。
本文将详细介绍M1卡的工作原理。
我们需要了解M1卡的基本结构。
M1卡由内部集成电路芯片和外部封装材料组成。
内部芯片包括存储器和处理器,用于存储和处理相关数据。
封装材料则起到保护芯片的作用,并提供与读写设备的物理连接。
M1卡的工作原理主要分为读取和写入两个过程。
在读取过程中,读写设备通过无线电频率与M1卡进行通信。
读写设备向M1卡发送指令,M1卡则根据指令执行相应操作,并将结果发送回读写设备。
在写入过程中,读写设备将要写入的数据发送给M1卡,M1卡将数据存储在内部存储器中。
M1卡的通信方式采用的是非接触式近场通信技术。
在通信过程中,读写设备通过电磁感应产生高频电磁场,M1卡则利用感应线圈接收读写设备发送的电磁信号,并利用感应线圈发送响应信号。
由于近场通信的特性,读写设备与M1卡之间的通信距离较短,一般在几厘米之内。
M1卡的工作原理还涉及到认证和加密机制。
为了保证数据的安全性,M1卡在与读写设备通信之前需要进行认证。
认证过程中,读写设备向M1卡发送认证密钥和相关指令,M1卡通过内部的加密算法进行认证,并返回认证结果。
只有认证成功的M1卡才能与读写设备进行数据交互。
除了认证机制,M1卡还支持数据的读写和修改操作。
读写设备可以向M1卡发送读取指令,M1卡将存储在内部存储器中的数据发送回读写设备。
同时,读写设备也可以向M1卡发送写入指令,将数据写入到M1卡的内部存储器中。
通过这种方式,M1卡可以实现数据的存储和传输功能。
M1卡还支持多种应用场景。
在支付领域,M1卡可以用作电子钱包,用户可以通过M1卡进行消费支付。
在门禁领域,M1卡可以用作身份识别凭证,用户可以通过M1卡进行门禁开关控制。
在地铁刷卡领域,M1卡可以用作乘车凭证,用户可以通过M1卡进行地铁刷卡乘车。
M1卡是一种运用近场通信技术的智能卡片,具有读写、认证和加密等功能。
手机NFC模拟M1门禁卡、写CUID白卡原理
手机NFC模拟M1门禁卡、写CUID白卡原理一、需求场景近来小区安装了智能门禁,但只配发了一张门禁卡,不方便使用,于是产生了用手机模拟门禁卡,或者复制一张门禁卡的想法。
包括手机NFC读写卡神器Mifare Classic Tool(MCT)2.2.5最新版、手机读卡工具NFC TagInfo、NFC卡模拟软件Card emulator、RE管理器,以及一款NFC模拟的小工具0.4(适配机型不多)。
(由于原理一致,本文只侧重于讨论手机NFC写白卡,不讨论PN532、PM3、COPY5等设备读写卡。
)二、卡片分类M1卡:全称Mifare classic1K,普通IC卡,0扇区不可修改,其他扇区可以反复擦写。
通常我们使用的门禁卡、电梯卡都是M1卡。
M1卡是NXP(恩智浦半导体)公司研发的IC卡,执行标准是ISO/IEC14443Type A,读写频率是13.56MHz。
目前大多数手机厂商使用的NFC芯片都是NXP,另一部分则是BRCM(博通)方案,均执行同一标准,这是手机读写M1卡的技术基础。
UID卡:普通复制卡,可以反复擦写所有扇区,门禁有防火墙则失效。
CUID:升级复制卡,可以反复擦写所有扇区,可以穿透大部分防火墙。
FUID:高级复制卡,0扇区只能写入一次,写入后变为M1卡。
UFUID:超高级复制卡,0扇区只能写入一次,封卡后变为M1卡,不封卡变为UID卡。
复制卡均可在网上购买,有普通卡片、钥匙扣、滴胶卡等类型,CUID通常1.5元/张,越高级的卡越贵。
三、M1卡的结构(计算机领域的计数均是从0开始)(M1卡标准储存的数据使用16进制,简称HEX,即由0-9、A-F组成,也写作0xAA)(一)存储结构Mifare classic1K,即存储容量1K=1024Byte,包括16个扇区,每个扇区含4个块,每个块16Byte.第0扇区比较特殊,0区0块前8位为厂商UID码,可以理解为M1卡的识别码。
0-2块为储存内容区间。
M1卡技术标准
银深源M1卡技术标准M1卡简介:M1芯片,是指菲利浦下属子公司恩智浦出品的芯片缩写,全称为NXP Mifare1系列,常用的有S50及S70两种型号。
目前已经有国产芯片与其兼容,利用PVC封装M1芯片、感应天线,然后压制成型后而制作的卡即是智能卡行业所说的M1卡,属于非接触式IC卡。
非接触式IC卡又称射频卡,成功地解决了无源(卡中无电源)和免接触这一难题,是电子器件领域的一大突破。
主要用于公交、轮渡、地铁等自动收费系统,也应用在门禁管理、身份证明和电子钱包。
M1卡,优点是可读可写的多功能卡,缺点是:价格稍贵,感应距离短,适合非定额消费系统、停车场系统、门禁考勤系统等。
M1卡工作原理:射频读写器向M1卡发一组固定频率的电磁波,卡片内有一个LC串联谐振电路,其频率与读写器发射的频率相同,在电磁波的激励下,LC谐振电路产生共振,从而使电容内有了电荷,在这个电容的另一端,接有一个单向导通的电子泵,将电容内的电荷送到另一个电容内储存,当所积累的电荷达到2V时,此电容可做为电源为其它电路提供工作电压,将卡内数据发射出去或接取读写器的数据。
M1(S50)卡详细规格:芯片类型:Philips Mifare 1 IC S50;存储容量:8Kbit,16个分区,每分区两组密码;工作频率:13.56 MHz;通讯速率:106KBoud;读写距离:2.5~10cm;读写时间:1~2ms;工作温度:-20℃~55℃;擦写寿命:>100,000次;数据保存:>10年;外形尺寸:ISO标准卡 85.6x54x0.82;封装材料:PVC、PET、PETG、0.13mm铜线;封装工艺:超声波自动植线/自动碰焊;执行标准:ISO14443A;典型应用:企业/校园一卡通、公交储值卡、高速公路收费、停车场、小区管理、会员卡、会员管理等。
M1(S70)卡详细规格:1、容量为 32K 位 EEPROM;2、分为 40 个扇区,其中 32 个扇区中每个扇区存储容量为 64 个字节,分为 4 块,每块16 个字节;以块为存取单位以块为存取单位;3、每个扇区有独立的一组密码及访问控制;4、每张卡有唯一序列号,为 32 位;5、具有防冲突机制,支持多卡操作;6、无电源,自带天线,内含加密控制逻辑和通讯逻辑电路;7、数据保存期为 10 年,可改写 10 万次,读无限次;8、工作温度: -20 ℃ ~50 ℃ ( 湿度为 90%);9、工作频率: 13.56MHZ;10、通信速率:106 KBPS;11、读写距离: 10 cm 以内(与读写器有关)。
WIFI接口M1卡读写器17WA系列说明书130910[分享]
17WA系列产品说明书一.功能17WA系列读写卡器是一种使用WIFI与计算机进行通讯的读写卡器,计算机可以通17WA读写MIFARE卡。
应用层的协议是使用TCP或UDP进行通信。
读卡器检测到刷卡后可以主动向计算机发送卡号,计算机无需轮询检测,计算机在接收到卡号后可以对卡片进行读、写、加减值等操作。
读卡器也可以不主动上传卡号而由计算机发送寻卡命令后再上传是否有卡的返回命令。
注意:1.如果读卡器在主动工作方式,当计算机发送寻卡命令后,读卡器就自动转入被动上传卡号状态,不再主动上传卡号,读卡器重新上电或接收恢复主动命令后,会自动恢复到刷卡主动上传卡号状态2.读卡器出厂设置中的300毫秒自动关卡功能:刷卡后读卡器主动上传卡号命令到计算机,计算机接收到上传的卡号命令后,需要在300毫秒内向读卡器发送一条命令,也就是说,读卡器在主动读到卡,直到关卡前,如果有300毫秒没有接收到计算机发来的命令,读卡器会主动关闭卡片,这时计算机再发命令来,也操作不了卡片了,这点必须注意。
3计算机向读卡器发送寻卡命令后,读卡器就会工作在被动上传卡号的状态,不主动读卡,不再主动上传卡号,且不会自动关卡,计算机发寻卡命令时寻到卡后,在对这张卡读写操作完成后,计算机需要发送关卡命令关闭这张卡,才能对其它卡的读写。
4.读卡器处在主动上传卡号的状态,要慎用把读卡器设置为300毫秒不自动关卡,因为设置成这样时,每次上传卡号后,在计算机操作读写完成后,都需要计算机发送一条关卡命令,如果刷卡上传的卡号后计算机读写完成没有发送关卡命令,读卡器不会主动读取其它靠近的卡片,这样会导致后边的人无法刷卡。
如果一定要用主动上传卡号模式且300毫秒不主动关卡,建议计算机定时发送关卡命令,防止卡号丢失的情况导致后边的人无法刷卡。
二.技术参数●工作电源:+5V DC●额定电流:<250mA●输出:LED发光管、蜂鸣器、汉字液晶屏●读卡器接口:WIFI接口●工作环境:温度-20℃~55℃,湿度0~90% 。
RFID之M1卡数据资料
0x01契机一直没有机会也没下定决心认真的去研究某个安全领域,很早之前就看到好多人研究RFID,一直很憧憬那片天空,趁着老大给机会,决定选这个方向作为个人业余努力的方向。
差不多四天前入手了ACR122U,决定拿自己母校的餐厅饭卡练手。
ACR122U的使用很简单,只要安装上驱动,使用M1卡服务程序就可以很快破解,破解完成后查看其生成的dump文件,找到加密扇区的密码,将密码导入到MCT (Mifare Classic Tool),剩下的就可以完全使用MCT 完成了,个人很怀疑破解过程是否完全可以通过手机(支持NFC)APP完成。
ACR122U的详细使用过程可以参考:RFID安全之某学校水卡破解,本文主要介绍目前M1卡中的数据分析和M1卡安全防护方案。
0x02背景知识了解M1卡的结构可以知道M1卡共16个扇区,编号从0到15,每个扇区配备了从0到3共4个段,每个段可以保存16字节的内容。
0x03数据分析阅读《RFID安全之某学校水卡破解》可以发现该学校的水卡中数据存储比较简单,按照作者的分析,4号扇区的1、2号数据段(编号从0开始)存储了水卡余额,将已知的余额32.31,换算为分为3231,再转为10进制为C9F,即00000C9F,而0C9F取反为FFFFF360,这时比较下4号扇区的值,很容易发现规律:前四个字节不取反倒序(9F0C0000)存储余额,接下来四个字节取反倒序(60F3FFFF)存储余额,再接下来四个字节不取反倒序(9F0C0000)存储余额。
上面提到的“倒序”,可以结合计算机数据存储方式来理解:如下图所示,变量a存储的数据对应的16进制为0A112233,变量b存储的数据对应的16进制为0B445566。
这样就很明显了,5634120A,就是变量a所代表的数据的十六进制0A123456的倒序。
作为入门教程,个人认为《RFID安全之某学校水卡破解》是非常不错的。
看完这个教程,并实践结束后,我停下来思考这样一个问题:M1卡的密码破解是傻瓜式的,当然也有文章介绍破解原理,但是作为门外汉,目前我还不是特别关心,我只想找到那种破解成功,可以修改金额的快感!那么在整个M1卡的破解过程中,我自己到底起了什么作用?答案是卡片的数据分析。
M1卡技术参数范文
M1卡技术参数范文
以下是M1卡的详细技术参数:
1.存储容量:M1卡共有16个扇区,每个扇区包含4个块,每个块的容量为16字节。
因此,M1卡的总存储容量为16*4*16=1024字节。
2. 数据传输速率:M1卡的标准传输速率为106 kb/s,实际传输速率可在标准传输速率的基础上进行扩展。
3.数据通讯距离:M1卡的最大识别距离为5厘米,也可根据需要调整。
4.安全性能:M1卡支持密码认证功能,每个扇区都有两个密码,分别称为“密钥A”和“密钥B”,用于控制对扇区中数据的读写权限。
密钥A拥有最高级别的权限,可以进行读写操作;密钥B只具备读取权限。
此外,M1卡还支持AES算法,提供更高级别的安全性。
5.使用寿命:M1卡的使用寿命长,一般可达到10万次的读写操作,并且具有很强的抗磁性和耐腐蚀性。
7.应用领域:由于M1卡具有高度安全性和广泛的兼容性,因此被广泛应用于各个领域。
在物流方面,可以用于产品追踪和库存管理;在金融领域,可以用于电子钱包和身份认证;在交通领域,可以用于公交卡或地铁卡。
此外,M1卡还可以应用于学生卡、门禁卡等。
总结:。
01智能卡基础知识M1卡
四、M1卡认证与指令
KeyA、KeyB的认证
三次互相确认(3 Pass Authentication): PCD PICC Auth(6x xx) —> <— RNG(B) TOKEN(AB) —> <— TOKEN(BA) android.nfc.tech.MifareClassic类中封装为: authenticateSectorWithKeyA() authenticateSectorWithKeyB()
控制字节介绍
每个块都有相应的三个控制位,定义如下: 块0: C10 C20 C30 块1: C11 C21 C31 块2: C12 C22 C32 块3: C13 C23 C33
控制字节介绍
控制位(X=0..2) C1X C2X C3X 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 0 0 0 0 1 1 1 1 访 问 条 件 (对数据块 0、1、2) Increment Decrement, Read Write transfer,Restore KeyA|B KeyA|B KeyA|B KeyA|B KeyA|B Never Never Never KeyA|B KeyB Never Never KeyA|B KeyB KeyB KeyA|B KeyA|B Never Never KeyA|B KeyB KeyB Never Never KeyB Never Never Never Never Never Never Never 密码A Write KeyA|B Never KeyB Never KeyA|B KeyB Never Never 存取控制 Read Write KeyA|B Never KeyA|B Never KeyA|B Never KeyA|B Never KeyA|B KeyA|B KeyA|B KeyB KeyA|B KeyB KeyA|B Never 密码B Read Write KeyA|B KeyA|B KeyA|B Never KeyB Never Never Never KeyA|B KeyA|B KeyB Never Never Never Never Never
M1卡具体操作
M1卡具体操作对于电脑周边编程,主要有两种思路(应该没有第三种了)。
【详细说明见我博文永和豆浆管理系统基础工作总结】一、利用windows系统本身dll库。
二、利用硬件产家提供的dll。
本篇对M1卡的编程是利用上述第二种方法。
M1卡最为重要的优点是可读可写并且安全性高的多功能卡。
这些优点与其自身的结构密不可分。
M1结构:M1卡分为16个扇区,每个扇区4块(块0~3),共64块,按块号编址为0~63。
第0扇区的块0(即绝对地址0块)用于存放厂商代码,已经固化,不可更改。
其他各扇区的块0、块1、块2为数据块,用于存贮数据;块3为控制块,存放密码A、存取控制、密码B。
每个扇区的密码和存取控制都是独立的,可以根据实际需要设定各自的密码及存取控制。
M1卡运作机理:连接读写器→寻卡→识别卡(获取卡序列号)→从多卡中选一张卡→向卡中缓冲区装载密码→验证密码→进行读写→关闭连接即(代码说明)Open_USB→rf_request→rf_anticoll→rf_select→rf_load_key→rf_authentication→(/a_hex)→rf_read/rf_write→(hex_a)→Close_ USB如果概括来说的话,主要也就四部分开关连接、寻卡、验证密码、读取。
(至于详细程序代码,相信大家自己看过dll说明文档后,自己会明白的,这里就不写了,因为内容多)M1卡功能模式:1.寻卡模式:寻卡模式分三种情况:IDLE模式、ALL模式及指定卡模式(0,1,2 均是int类型,是方法参数,下同)。
0——表示IDLE模式,一次只对一张卡操作;1——表示ALL模式,一次可对多张卡操作;2——表示指定卡模式,只对序列号等于snr的卡操作(高级函数才有)【不常用】也就是说,我们一次也可以同时操作多张卡。
对于多卡操作,其实际真正执行操作的还是一张卡。
读写器能识别多张卡的序列号(但注意识别出的顺序是不定的,并且最多也就能识别4张卡,因为卡叠放的厚度太厚,会超出读写器的识别范围),并一一进行操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
非接触式IC卡性能简介(M1卡)
一、主要指标
●容量为8K位EEPROM
●分为16个扇区,每个扇区为4块,每块16个字节,以块为存取单位
●每个扇区有独立的一组密码及访问控制
●每张卡有唯一序列号,为32位
●具有防冲突机制,支持多卡操作
●无电源,自带天线,内含加密控制逻辑和通讯逻辑电路
●数据保存期为10年,可改写10万次,读无限次
●工作温度:-20℃~50℃(湿度为90%)
●工作频率:13.56MHZ
●通信速率:106 KBPS
●读写距离:10 cm以内(与读写器有关)
二、存储结构
1、M1卡分为16个扇区,每个扇区由4块(块0、块1、块
2、块3)组成,(我们也
将16个扇区的64个块按绝对地址编号为0~63,存贮结构如下图所示:
数据块0
数据块 1
数据块 2
控制块 3
数据块 4
数据块 5
数据块 6
控制块7
数据块60
数据块61
数据块62
控制块63
2、第0扇区的块0(即绝对地址0块),它用于存放厂商代码,已经固化,不可更改。
3、每个扇区的块0、块1、块2为数据块,可用于存贮数据。
数据块可作两种应用:
★ 用作一般的数据保存,可以进行读、写操作。
★ 用作数据值,可以进行初始化值、加值、减值、读值操作。
4、每个扇区的块3为控制块,包括了密码A 、存取控制、密码B 。
具体结构如下:
密码A (6字节) 存取控制(4字节) 密码B (6字节)
5、每个扇区的密码和存取控制都是独立的,可以根据实际需要设定各自的密码及存取控制。
存取控制为4个字节,共32位,扇区中的每个块(包括数据块和控制块)的存取条件是由密码和存取控制共同决定的,在存取控制中每个块都有相应的三个控制位,定义如下:
块0: C10 C20 C30 块1: C11 C21 C31 块2: C12 C22 C32 块3: C13 C23 C33
三个控制位以正和反两种形式存在于存取控制字节中,决定了该块的访问权限(如 进行减值操作必须验证KEY A ,进行加值操作必须验证KEY B ,等等)。
三个控制 位在存取控制字节中的位置,以块0为例:
对块0的控制:
字节6 字节7 字节8 字节9
( 注: C10_b 表示C10取反 )
存取控制(4字节,其中字节9为备用字节)结构如下所示:
字节6 字节7 字节8 字节9
( 注: _b 表示取反 )
6、数据块(块0、块1、块2)的存取控制如下:
(KeyA|B 表示密码A或密码B,Never表示任何条件下不能实现)
例如:当块0的存取控制位C10 C20 C30=1 0 0时,验证密码A或密码B正确后可读;
验证密码B正确后可写;不能进行加值、减值操作。
7、控制块块3的存取控制与数据块(块0、1、2)不同,它的存取控制如下:
例如:当块3的存取控制位C13 C23 C33=1 0 0时,表示:
密码A:不可读,验证KEYA或KEYB正确后,可写(更改)。
存取控制:验证KEYA或KEYB正确后,可读、可写。
密码B:验证KEYA或KEYB正确后,可读、可写。
三、工作原理
卡片的电气部分只由一个天线和ASIC组成。
天线:卡片的天线是只有几组绕线的线圈,很适于封装到IS0卡片中。
ASIC:卡片的ASIC由一个高速(106KB波特率)的RF接口,一个控制单元和一个8K位EEPROM组成。
工作原理:读写器向M1卡发一组固定频率的电磁波,卡片内有一个LC串联谐振电路,其频率与讯写器发射的频率相同,在电磁波的激励下,LC谐振电路产生共振,从而使电容内有了电荷,在这个电容的另一端,接有一个单向导通的电子泵,将电容内的电荷
送到另一个电容内储存,当所积累的电荷达到2V时,此电容可做为电源为其它电路提供工作电压,将卡内数据发射出去或接取读写器的数据。
四、M1射频卡与读写器的通讯
复位应答(Answer to request)
M1射频卡的通讯协议和通讯波特率是定义好的,当有卡片进入读写器的操作范围时,读写器以特定的协议与它通讯,从而确定该卡是否为M1射频卡,即验证卡片的卡型。
防冲突机制(Anticollision Loop)
当有多张卡进入读写器操作范围时,防冲突机制会从其中选择一张进行操作,未选中的则处于空闲模式等待下一次选卡,该过程会返回被选卡的序列号。
选择卡片(Select Tag)
选择被选中的卡的序列号,并同时返回卡的容量代码。
三次互相确认(3 Pass Authentication)
选定要处理的卡片之后,读写器就确定要访问的扇区号,并对该扇区密码进行密码校验,在三次相互认证之后就可以通过加密流进行通讯。
(在选择另一扇区时,则必须进行另一扇区密码校验。
)
对数据块的操作
读(Read):读一个块;
写(Write):写一个块;
加(Increment):对数值块进行加值;
减(Decrement):对数值块进行减值;
存储(Restore):将块中的内容存到数据寄存器中;
传输(Transfer):将数据寄存器中的内容写入块中;
中止(Halt):将卡置于暂停工作状态;。