美文网首页
浅谈M1卡

浅谈M1卡

作者: guanalex | 来源:发表于2017-07-30 17:50 被阅读3443次

    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;
    }
    

    相关文章

      网友评论

          本文标题:浅谈M1卡

          本文链接:https://www.haomeiwen.com/subject/qihklxtx.html