浅谈M1卡

M1卡就是Mifare非接触式感应卡,M1卡数据保存期为10年,可改写10万次,读无限次。无电源,自带天线,工作频率为13.56MHZ.M1卡内含加密控制逻辑和通讯逻辑电路。M1卡主要有两种,一种是S50和一种是S70。

M1卡的工作原理

读写器向M1卡发一组固定频率的电磁波,卡片内有一个 LC串联谐振电路,其频率与读写器发射的频率相同,在电磁波的激励下,LC谐振电路产生共振,从而使电容内有了电荷,在这个电容的另一端,接有一个单向导通的电子泵,将电容内的电荷送到另一个电容内储存,当所积累的电荷达到2V时,此电容可做为电源为其它电路提供工作电压,将卡内数据发射出去或接取读写器的数据。简单地说,就是感应产生电流来工作的一种卡片。

存储结构

M1卡存储扇区

第0扇区的块0(即绝对地址0块),它用于存放厂商代码,已经固化,不可更改。
每个扇区的块0、块1、块2为数据块,可用于存贮数据。数据块可作两种应用:
★ 用作一般的数据保存,可以进行读、写操作。
★ 用作数据值,可以进行初始化值、加值、减值、读值操作。
而每个扇区的控制块,包括了密码A、存取控制、密码B。具体结构如下:


控制块的结构

每个扇区都是独立的,也就是说,每个扇区都可以设置独立的密码和数据,从而实现一卡多用的好处,对于每个扇区的数据块的数据写入具有一定的格式要求,比如在用于余额计算的钱包功能时数据的格式为


数据块格式

寻卡

首先我们用读卡器读卡时,读卡器发送相应的指令寻取感应区内的某一指定类型的卡片。

防冲撞

当寻完卡后,就进入防冲撞,避免多卡乱像,此时读取卡片序列号,对于卡片的序列号,经过多次测验可以确定它的格式为十六进制的4字节数组,网上很多资料并没有说明此序列号的格式,所以在用单片机发送出去时必须转换格式才能正常显示。

选定卡片

选择被选中的卡的序列号,并同时返回卡的容量代码。

验证卡片密码

选定要处理的卡片之后,读写器就确定要访问的扇区号,并对该扇区密码进行密码校验,在三次相互认证之后就可以通过加密流进行通讯。(在选择另一扇区时,则必须进行另一扇区密码校验。)。一般的白卡的默认密码为6个0xFF数组,所以有些破解方法还是的破解密钥才进行修改数值的。

读取数据/写入数据

验证密码后就能进行读取相应扇区的数据了。</br>

/////////////////////////////////////////////////////////////////////
//功 能:寻卡
//参数说明: req_code[IN]:寻卡方式
// 0x52 = 寻感应区内所有符合14443A标准的卡
// 0x26 = 寻未进入休眠状态的卡
// pTagType[OUT]:卡片类型代码
// 0x4400 = Mifare_UltraLight
// 0x0400 = Mifare_One(S50)
// 0x0200 = Mifare_One(S70)
// 0x0800 = Mifare_Pro(X)
// 0x4403 = Mifare_DESFire
//返 回: 成功返回MI_OK //其中MI_OK=0
/////////////////////////////////////////////////////////////////////
`

     char PcdRequest(unsigned char req_code,unsigned char            *pTagType) 
{
     char status;   //status状态
     unsigned int  unLen;
     unsigned char ucComMF522Buf[MAXRLEN];  //存储卡类型的数组
     ClearBitMask(Status2Reg,0x08);    //清RC522寄存器位函数
     WriteRawRC(BitFramingReg,0x07);  //    写RC632寄存器函数
     SetBitMask(TxControlReg,0x03);   //置RC522寄存器位函数
     ucComMF522Buf[0] = req_code;
   status =         PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522    Buf,&unLen); //数组ucComMF522Buf已通过函数PcdComMF522()读取得卡信息,其中unLen为数据长度
   if ((status == MI_OK) && (unLen == 0x10))
     {    
         *pTagType     = ucComMF522Buf[0];
         *(pTagType+1) = ucComMF522Buf[1];  //使指针指向下一个地址
   }
   else
     {   status = MI_ERR;   }

        return status;
    }

/////////////////////////////////////////////////////////////////////
//功 能:防冲撞
//参数说明: pSnr[OUT]:卡片序列号,4字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////

    char PcdAnticoll(unsigned char *pSnr)  //防冲撞函数
{
char status;
unsigned char i,snr_check=0;
unsigned int  unLen;
unsigned char ucComMF522Buf[MAXRLEN]; 
ClearBitMask(Status2Reg,0x08);
WriteRawRC(BitFramingReg,0x00);
ClearBitMask(CollReg,0x80);
ucComMF522Buf[0] = PICC_ANTICOLL1;
ucComMF522Buf[1] = 0x20;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);
if (status == MI_OK)
{
     for (i=0; i<4; i++)
     {   
         *(pSnr+i)  =ucComMF522Buf[i] ;
         temp_ucTempbuf[i]=ucComMF522Buf[i];
         if(temp_ucTempbuf[1]==16)
          sen_char(temp_ucTempbuf[0]);
         snr_check ^= ucComMF522Buf[i];
         //sen_char(snr_check);
     }
     if (snr_check != ucComMF522Buf[i])
     {   status = MI_ERR;    }
}    
SetBitMask(CollReg,0x80);

return status;
}

/////////////////////////////////////////////////////////////////////
//功 能:选定卡片
//参数说明: pSnr[IN]:卡片序列号,4字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////

char PcdSelect(unsigned char *pSnr)  //选定卡片函数
{
char status;
unsigned char i;
unsigned int  unLen;
unsigned char ucComMF522Buf[MAXRLEN];    
ucComMF522Buf[0] = PICC_ANTICOLL1;
ucComMF522Buf[1] = 0x70;
ucComMF522Buf[6] = 0;
for (i=0; i<4; i++)
{
    ucComMF522Buf[i+2] = *(pSnr+i);
    ucComMF522Buf[6]  ^= *(pSnr+i);
}
CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);  
ClearBitMask(Status2Reg,0x08);
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);    
if ((status == MI_OK) && (unLen == 0x18))
{   status = MI_OK;  }
else
{   status = MI_ERR;    }
return status;
}

/////////////////////////////////////////////////////////////////////
//功 能:验证卡片密码
//参数说明: auth_mode[IN]: 密码验证模式
// 0x60 = 验证A密钥
// 0x61 = 验证B密钥
// addr[IN]:块地址
// pKey[IN]:密码
// pSnr[IN]:卡片序列号,4字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////

  char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr)  //验证卡片密码
{
char status;
unsigned int  unLen;
unsigned char i,ucComMF522Buf[MAXRLEN]; 
ucComMF522Buf[0] = auth_mode;
ucComMF522Buf[1] = addr;
for (i=0; i<6; i++)
{    ucComMF522Buf[i+2] = *(pKey+i);   }
for (i=0; i<6; i++)
{    ucComMF522Buf[i+8] = *(pSnr+i);   } 
status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
{   status = MI_ERR;   }    
return status;
}

/////////////////////////////////////////////////////////////////////
//功 能:读取M1卡一块数据
//参数说明: addr[IN]:块地址
// pData[OUT]:读出的数据,16字节
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////

 char PcdRead(unsigned char addr,unsigned char *pData)  //读取M1卡一块数据函数
{
char status;
unsigned int  unLen;
unsigned char i,ucComMF522Buf[MAXRLEN]; 
ucComMF522Buf[0] = PICC_READ;
ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);   
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
{
    for (i=0; i<16; i++)
    {    *(pData+i) = ucComMF522Buf[i];   }
}
else
{   status = MI_ERR;   }    
return status;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • M1卡分为16个扇区,每个扇区由4块(块0、块1、块2、块3)组成,(我们也将16个扇区的64个块按绝对地址编号为...
    旅行家John阅读 4,825评论 0 1
  • 系统的原理 这套系统是由各个模块来组成,它们分别是51单片机(这里用集成开发板)、12864液晶显示模块,WiFi...
    guanalex阅读 5,362评论 0 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 岁月匆匆小满到, 初夏炎炎夏收季。 时令作物待成熟, 汗滴大地亦欢喜! 2017.5.21中午
    白丰阁阅读 176评论 0 0
  • 现在这个社会,越来越多的人渴望获得成功,甚至是极端的成功。然而,绝大部分人根本想象不到获得所谓成功需要付出的代价。...
    胆小的鳄鱼阅读 949评论 3 4