|
52單片機(jī)驅(qū)動(dòng)rc522讀cpu卡資料包:
單片機(jī)源程序如下:
- #include "reg52.h"
- #include <string.h>
- #include <intrins.h>
- #include "main.h"
- #include "RC522.H"
- #include "12864.h"
- #include "uart.h"
- #include "FM1208.H"
- #include "psam.h"
- unsigned char Serial_Num[8]; //用戶卡序列號(hào)
- unsigned char code S_KEY_1[8]={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88}; //分散因子1(為自定義城市標(biāo)識(shí))
- unsigned char code S_KEY_2[8]={0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11}; //分散因子2(為自定義各成員銀行標(biāo)識(shí))
- //////////////////文件標(biāo)識(shí)的定義/////////////////////////////////////////////////////////////////////////////////
- //
- //為統(tǒng)一方便管理閱讀代碼,我們?cè)谒械奈募竺婕觽(gè)_Flag,表示就是該對(duì)應(yīng)文件的標(biāo)識(shí)//
- //
- unsigned char code CZKey_Flag={0x01}; //圈存密鑰標(biāo)識(shí)為01
- unsigned char code DPKey_Flag={0x00}; //消費(fèi)密鑰標(biāo)識(shí)為00
- unsigned char code DF_ExKey_Flag = {0x00}; //DF下的外部密鑰標(biāo)識(shí)00
- unsigned char code DF_Inital_Key_Flag = {0x00}; //DF下的內(nèi)部密鑰標(biāo)識(shí)00
- unsigned char code FM1208_DF_0015_Flag[]={0x00,0x15}; //公共應(yīng)用基本數(shù)據(jù)文件標(biāo)識(shí)0015
- unsigned char code FM1208_DF_0016_Flag[]={0x00,0x16}; //持卡人基本信息數(shù)據(jù)的文件標(biāo)識(shí)0016
- ////////////////////////////////////////////////////////////////////////
- //文件標(biāo)識(shí)
- unsigned char code File_3F00[] ={0x3f,0x00}; //MF下的文件標(biāo)識(shí)3F00
- unsigned char code File_3F01[] ={0x3f,0x01}; //DF下的文件標(biāo)識(shí)3F01
- unsigned char code File_0016={0x16}; //終端機(jī)短文件標(biāo)識(shí)
- unsigned char Temporary_Key[8];
- unsigned char xdata Challenge_Num[8]; //隨機(jī)數(shù)
- unsigned char code DateTime[]={0x20,0x16,0x10,0x26,0x11,0x32,0x45}; //交易時(shí)間,如果板子帶有時(shí)鐘芯片,可以把實(shí)時(shí)時(shí)間寫入卡中。
- unsigned char xdata NameBuf[20]; //臨時(shí)存放姓名
- unsigned char xdata NameLen; //姓名長(zhǎng)度
- unsigned char code Purchase_Pay[4]={0x00,0x00,0x00,0x01}; //操作的金額 高位在前,16進(jìn)制計(jì)算的,定額消費(fèi)1元
- unsigned int xdata PAY;
- unsigned int xdata Pay_1 ;
- unsigned char xdata POSNum[6]; //終端機(jī)編號(hào) 從SAM卡中讀取
- unsigned char xdata g_cSNR[4];
- unsigned char xdata DataBuf[MAXRLEN];
- unsigned char xdata g_cReceBuf[MAXRLEN];
-
- void NameToStr(char *s) //計(jì)算姓名的長(zhǎng)度,及臨時(shí)保存姓名
- {
- char i;
- NameLen=strlen(s);
-
- for(i=0;i<NameLen;i++)
- NameBuf[i]=s[i];
- }
- void CLRBuff()
- {
- memset(g_cReceBuf, 0x00, MAXRLEN); //清0
- memset(DataBuf, 0x00, MAXRLEN);
- }
- void Request_loop()
- {
- s8 status,atq[2] ;
- while(1)
- {
- status = PcdRequest(PICC_REQALL, atq);
- if(status != MI_OK)
- {
- status = PcdRequest(PICC_REQALL, atq);
- if(status != MI_OK)
- break;
- }
- }
- }
- void main( )
- {
- unsigned int xdata st;
- unsigned char xdata tt[2];
- unsigned char xdata i;
- unsigned char status;
- InitializeSystem( );
- DelayMs(200); //等待上電穩(wěn)定
- UART_Init(); //串口初始化
- RC522_Init(); //RC522初始化 ,
- initial_LCD(); //顯示屏初始化
-
- if(PSAMInit(g_cReceBuf)) //PSAM卡初始化
- {
- UART_Send_Str("無(wú)PSAM卡,請(qǐng)插入PSAM卡!");
- UART_Send_Enter();
- while(1);
- }
- UART_Send_Str("PSAM卡復(fù)位成功!");
- UART_Send_Enter();
- Dis_Deduct_Charge(0); //12864顯示
-
- PcdAntennaOff();
- DelayMs(3);
- PcdAntennaOn();
- CLRBuff();
- while ( 1 )
- {
-
- st =PcdRequest(PICC_REQALL, tt); //尋卡
- if(st){continue;}
- st =PcdAnticoll(g_cSNR);//防沖撞,
- if(st){continue;}
-
- st =PcdSelect(g_cSNR); //選擇卡片
- if(st){continue;}
-
-
- if (pro_reset(g_cReceBuf,tt)!=MI_OK) //用戶卡(CPU卡)復(fù)位,成功后才能往下操作//
- {
- CLRBuff();
- continue;
- }
- UART_Send_Enter();
- UART_Send_Enter();
- UART_Send_Str("用戶卡復(fù)位成功!");
- UART_Send_Enter();
- UART_Send_Enter();
-
- ////////////////////////////////////////////////////////////////
- CLRBuff();
- st=Sam_Select_File(File_3F00, 2, 0,g_cReceBuf, 0x28 ); //選擇SAM卡中PBOC的3F00文件// 0x2E
- if(st!=SAM_OK)
- {
- UART_Send_Str("SAM卡3F00文件打開錯(cuò)誤:");
- UART_Put_Num(g_cReceBuf,2); //顯示錯(cuò)誤代碼
- UART_Send_Enter();
- CLRBuff();
- Request_loop();
- continue;
- }
- CLRBuff();
- st=Sam_ReadBinary( File_0016,g_cReceBuf, 6 ); //讀取SAM卡里面的終端機(jī)編號(hào)//
- if(st!=SAM_OK)
- {
- UART_Send_Str("SAM卡的終端機(jī)編號(hào)讀取錯(cuò)誤:");
- UART_Put_Num(g_cReceBuf,2); //顯示錯(cuò)誤代碼
- UART_Send_Enter();
- CLRBuff();
- Request_loop();
- continue;
-
- }
- UART_Send_Str("終端機(jī)編號(hào)為:");
- memcpy(POSNum, g_cReceBuf, 6);
- UART_Put_Num(POSNum,6);
-
- UART_Send_Enter();
- CLRBuff();
- st=Sam_Select_File(File_3F01, 2, 0,g_cReceBuf, 0x27 ); //選擇SAM卡中PBOC的3F01文件
- if(st!=SAM_OK)
- {
- UART_Send_Str("SAM卡PBOC文件打開錯(cuò)誤:");
- UART_Put_Num(g_cReceBuf,2); //顯示錯(cuò)誤代碼
- UART_Send_Enter();
- CLRBuff();
- Request_loop();
- continue;
-
- }
- UART_Send_Str("SAM卡PBOC文件打開成功!");
- UART_Send_Enter();
- UART_Send_Enter();
-
- CLRBuff();
- st=FM1208_SelectFile(File_3F01,g_cReceBuf,tt); //打開CPU卡中PBOC的3F01文件//
- if(st!=0x9000)
- {
- if(st!=ST_ERR)
- {
- UART_Send_Str("用戶卡PBOC文件打開錯(cuò)誤!");
- UART_Send_Enter();
- }
- CLRBuff();
- Request_loop();
- continue;
- }
- UART_Send_Str(">>用戶卡PBOC文件打開成功<<");
- UART_Send_Enter();
- UART_Send_Enter();
- CLRBuff();
- st=FM1208_Read_Binary(FM1208_DF_0015_Flag[1],g_cReceBuf, 0x1E ); //讀取0015文件公共應(yīng)用基本數(shù)據(jù)//
- if(st!=0x9000)
- {
- if(st!=ST_ERR)
- {
- UART_Send_Str("公共應(yīng)用基本文件讀取失敗:");
- UART_Put_Num(g_cReceBuf,2);
- UART_Send_Enter();
- }
- CLRBuff();
- Request_loop();
- continue;
- }
- UART_Send_Str(">>公共應(yīng)用基本文件讀取成功<<");
- UART_Send_Enter();
- UART_Send_Enter();
-
- memcpy(Serial_Num, &g_cReceBuf[12], 8); //拷入用戶卡序號(hào)
- UART_Send_Str("用戶卡序號(hào):");
- UART_Put_Num(Serial_Num,8); //用戶卡序號(hào)
- UART_Send_Enter();
-
- UART_Send_Str("啟動(dòng)日期:");
- UART_Put_Num(&g_cReceBuf[20],4); //這里可做判斷一張卡的生命周期
- UART_Send_Str("停用日期:");
- UART_Put_Num(&g_cReceBuf[24],4);
- UART_Send_Enter();
-
-
-
-
-
- //////////////////////////////////////////////////////////////
- //主要是用戶卡判斷終端的合法性,即是否是有人偽造的終端機(jī)
-
- st=FM1208_GetChallenge(8,Challenge_Num); //從用戶卡取一組隨機(jī)數(shù)//
- if(st!=0x9000)
- {
- if(st!=ST_ERR)
- {
- UART_Send_Str("用戶卡讀取隨機(jī)碼錯(cuò)誤:");
- UART_Put_Num(g_cReceBuf,2);
- UART_Send_Enter();
- }
- CLRBuff();
- Request_loop();
- continue;
- }
-
- UART_Send_Str("取得隨機(jī)數(shù)");
- UART_Put_Num(Challenge_Num,8);
- UART_Send_Enter();
- CLRBuff();
- st=Init_for_descrypt(Serial_Num, 0x8, 0x27,DF_ExKey_Flag, g_cReceBuf); //用3DE初始化 1級(jí)分散產(chǎn)生過(guò)程密鑰 27--密鑰用途,為加密密鑰
- if(st!=SAM_OK)
- {
- UART_Send_Str("SAM卡的3DES初始化失敗:");
- UART_Put_Num(g_cReceBuf,2); //顯示錯(cuò)誤代碼
- UART_Send_Enter();
- CLRBuff();
- Request_loop();
- continue;
- }
- CLRBuff();
- st=Descrypt(Challenge_Num, 0x8, 0, g_cReceBuf, 0x8 ); //3DES算法 對(duì)剛才臨時(shí)保存的隨機(jī)數(shù)進(jìn)行加密//
- if(st!=SAM_OK)
- {
- UART_Send_Str("SAM卡的3DES計(jì)算錯(cuò)誤:");
- UART_Put_Num(g_cReceBuf,2); //顯示錯(cuò)誤代碼
- UART_Send_Enter();
- CLRBuff();
- Request_loop();
- continue;
- }
- UART_Send_Str("外部認(rèn)證的加密結(jié)果:");
- UART_Put_Num(g_cReceBuf,8);
- memcpy(Temporary_Key, g_cReceBuf, 8); //臨時(shí)保存加密結(jié)果
- UART_Send_Enter();
- CLRBuff();
- st=FM1208_External_Authenticate(DF_ExKey_Flag,Temporary_Key,g_cReceBuf);
- if(st!=0x9000)
- {
- if(st!=ST_ERR)
- {
- UART_Send_Str("終端POS機(jī)非法,外部認(rèn)證錯(cuò)誤:");
- UART_Put_Num(g_cReceBuf,2);
- UART_Send_Enter();
- }
- CLRBuff();
- Request_loop();
- continue;
- }
- UART_Send_Str("外部認(rèn)證成功,終端POS機(jī)合法!");
- UART_Send_Enter();
- UART_Send_Enter();
-
- ////////////////////////////////////////////////////////////////////
-
- //////////////////////////////////////////////////////////////
- //主要用于終端判斷卡的合法性,也就是說(shuō)你這張用戶卡是否能在我的終端上使用
- st=Get_challenge(Challenge_Num, 8); //從SAM卡里取一組隨機(jī)數(shù)//
- if(st!=SAM_OK)
- {
- UART_Send_Str("SAM卡讀取隨機(jī)碼錯(cuò)誤:");
- UART_Put_Num(g_cReceBuf,2); //顯示錯(cuò)誤代碼
- UART_Send_Enter();
- CLRBuff();
- Request_loop();
- continue;
- }
-
- CLRBuff();
- st=FM1208_Inital_Authenticate(DF_Inital_Key_Flag, 8, Challenge_Num,g_cReceBuf); //用戶卡內(nèi)部認(rèn)證,加密該隨機(jī)數(shù)//
- if(st!=0x9000)
- {
- UART_Send_Str("內(nèi)部認(rèn)證錯(cuò)誤:");
- UART_Put_Num(g_cReceBuf,2); //顯示錯(cuò)誤代碼
- UART_Send_Enter();
- CLRBuff();
- Request_loop();
- continue;
- }
- memcpy(Temporary_Key, g_cReceBuf, 8); //臨時(shí)保存加密結(jié)果
-
- CLRBuff();
- st=Init_for_descrypt(Serial_Num, 0x8, 0x2C, DF_Inital_Key_Flag, g_cReceBuf); //用3DE初始化 1級(jí)分散產(chǎn)生過(guò)程密鑰 2C--密鑰用途,為解密密鑰
- if(st!=SAM_OK)
- {
- UART_Send_Str("SAM卡的3DES初始化失敗:");
- UART_Put_Num(g_cReceBuf,2); //顯示錯(cuò)誤代碼
- UART_Send_Enter();
- CLRBuff();
- Request_loop();
- continue;
- }
- CLRBuff();
- st=Descrypt(Temporary_Key, 0x8, 0, g_cReceBuf, 0x8 ); //3DES算法 對(duì)剛才臨時(shí)保存的加密了的數(shù)據(jù)進(jìn)行解密//
- if(st!=SAM_OK)
- {
- UART_Send_Str("SAM卡的3DES計(jì)算錯(cuò)誤:");
- UART_Put_Num(g_cReceBuf,2); //顯示錯(cuò)誤代碼
- UART_Send_Enter();
- CLRBuff();
- Request_loop();
- continue;
- }
- UART_Send_Str("內(nèi)部認(rèn)證的解密結(jié)果:");
- UART_Put_Num(g_cReceBuf,8);
- UART_Send_Enter();
- for(i=0;i<8;i++)
- {
- if(g_cReceBuf[i]!=Challenge_Num[i]) //這里判斷卡的合法性//
- {
- status=1;
- break;
- }
- }
- if(status==1)
- {
- status=0;
- UART_Send_Str("非法卡!不能在本終端使用!");
- UART_Send_Enter();
- CLRBuff();
- Request_loop();
- continue;
- }
- UART_Send_Str("內(nèi)部認(rèn)證成功,用戶卡合法!");
- UART_Send_Enter();
- UART_Send_Enter();
-
- ////////////////////////////////////////////////////////////////////
-
- CLRBuff();
- st=FM1208_Read_Binary(FM1208_DF_0016_Flag[1],g_cReceBuf, 0x27 ); //讀取0016文件持卡人基本信息
- if(st!=0x9000)
- {
- if(st!=ST_ERR)
- {
- UART_Send_Str("持卡人基本信息文件讀取失敗:");
- UART_Put_Num(g_cReceBuf,2);
- UART_Send_Enter();
- }
- CLRBuff();
- Request_loop();
- continue;
- }
- UART_Send_Str(">>持卡人基本信息文件讀取成功<<");
- UART_Send_Enter();
- UART_Send_Enter();
- UART_Send_Str("卡類型標(biāo)識(shí):");
- UART_Put_Num(&g_cReceBuf[0],1);
- UART_Send_Enter();
- UART_Send_Str("本行職工標(biāo)識(shí):");
- UART_Put_Num(&g_cReceBuf[1],1);
- UART_Send_Enter();
- UART_Send_Str("持 卡 人 的姓名:");
- UART_Send_Str(&g_cReceBuf[2]);
- NameToStr(&g_cReceBuf[2]);
- UART_Send_Enter();
- UART_Send_Enter();
- UART_Send_Str("持 卡 人 的證件類型:");
- UART_Put_Num(&g_cReceBuf[38],1);
- UART_Send_Enter();
- UART_Send_Str("持 卡 人 的證件號(hào)碼:");
- UART_Put_Num(&g_cReceBuf[22],16);
- UART_Send_Enter();
-
- CLRBuff();
- DataBuf[0]=DPKey_Flag; //1個(gè)字節(jié)的消費(fèi)密鑰標(biāo)識(shí)
- memcpy(&DataBuf[1], Purchase_Pay, 4); //4個(gè)字節(jié)的交易金額,即扣款金額
- memcpy(&DataBuf[5], POSNum, 6); //6個(gè)字節(jié)的終端機(jī)編號(hào)
-
- st=FM1208_Initalize_For_Purchase(EP, DataBuf,g_cReceBuf,tt); //消費(fèi)初始化操作//
- if(st!=0x9000)
- {
- if(st!=ST_ERR)
- {
- UART_Send_Str("初始化消費(fèi)錯(cuò)誤:");
- UART_Put_Num(g_cReceBuf,tt[0]); //當(dāng)返回9403時(shí),此時(shí)檢查一下你的用戶卡里面的消費(fèi)密鑰的標(biāo)識(shí)號(hào),是否對(duì)應(yīng)?
- UART_Send_Enter();
- if(st==0x9401)
- DisNotMoney(); //卡余額不足
- DelayMs(2000);
- Dis_Deduct_Charge(0);
- }
- CLRBuff();
- Request_loop();
- continue;
- }
-
- UART_Send_Str(">>消費(fèi)初始化成功<<");
- UART_Send_Enter();
- UART_Send_Enter();
-
- UART_Send_Str("電子錢包未消費(fèi)前的余額:");
- UART_Put_Num(g_cReceBuf,4);
- UART_Send_Enter();
- UART_Send_Str("電子錢 包 交 易序號(hào):");
- UART_Put_Num(&g_cReceBuf[4],2);
- UART_Send_Enter();
- UART_Send_Str(" 限 額:");
- UART_Put_Num(&g_cReceBuf[6],3);
- UART_Send_Enter();
- UART_Send_Str("密鑰版本號(hào):");
- UART_Put_Num(&g_cReceBuf[9],1);
- UART_Send_Enter();
- UART_Send_Str("算法標(biāo)識(shí):");
- UART_Put_Num(&g_cReceBuf[10],1);
- UART_Send_Enter();
- UART_Send_Str("偽隨機(jī)碼:");
- UART_Put_Num(&g_cReceBuf[11],4);
- UART_Send_Enter();
-
-
-
- PAY=g_cReceBuf[2]<<8;
- PAY|=g_cReceBuf[3];
- Dis_Money(NameLen,NameBuf,PAY); //屏顯示消費(fèi)前的余額
-
- memcpy(DataBuf, &g_cReceBuf[11], 4); //拷偽隨機(jī)數(shù)
- memcpy(&DataBuf[4], &g_cReceBuf[4], 2); //用戶卡交易序號(hào)
- memcpy(&DataBuf[6], Purchase_Pay, 4); //交易金額
- DataBuf[10]=0x06; //交易類型
- memcpy(&DataBuf[11], DateTime, 7); //交易日期時(shí)間
- DataBuf[18]=DPKey_Flag; //消費(fèi)密鑰版本標(biāo)識(shí)號(hào)
- DataBuf[19]=0x00; //算法標(biāo)識(shí),3DES
- memcpy(&DataBuf[20], Serial_Num, 8); //用戶卡序號(hào)
- memcpy(&DataBuf[28], S_KEY_2, 8); //分散因子2(為各成員銀行標(biāo)識(shí))
- memcpy(&DataBuf[36], S_KEY_1, 8); //分散因子1(為各城市標(biāo)識(shí))
-
- st=Init_SAM_For_Purchase(DataBuf, 0x2C, g_cReceBuf); //MAC1計(jì)算初始化//
- if(st!=SAM_OK)
- {
- UART_Send_Str("MAC1計(jì)算錯(cuò)誤:"); //當(dāng)返回9403時(shí),此時(shí)檢查一下你的SAM卡里面的消費(fèi)密鑰的版本標(biāo)識(shí)號(hào),是否對(duì)應(yīng)?
- UART_Put_Num(g_cReceBuf,0x02);
- UART_Send_Enter();
- CLRBuff();
- Request_loop();
- Dis_Deduct_Charge(0);
- continue;
- }
-
- UART_Send_Str(">>MAC1計(jì)算初始化成功<<");
- UART_Send_Enter();
- UART_Send_Enter();
- UART_Send_Str("終端交易序號(hào):");
- UART_Put_Num(g_cReceBuf,0x04);
- UART_Send_Enter();
- UART_Send_Str("返回的MAC1碼:");
- UART_Put_Num(&g_cReceBuf[4],0x04);
- UART_Send_Enter();
-
- memcpy(DataBuf, g_cReceBuf, 4); //拷終端交易序號(hào)
- memcpy(&DataBuf[4], DateTime, 7); //拷交易日期時(shí)間
- memcpy(&DataBuf[11], &g_cReceBuf[4], 4); //拷MAC1
-
- st=FM1208_Debit_For_Capp_Purchase(DataBuf,g_cReceBuf,tt); //消費(fèi)命令//
- if(st!=0x9000)
- {
- if(st!=ST_ERR)
- {
- UART_Send_Str("扣款失敗:");
- UART_Put_Num(g_cReceBuf,tt[0]); //當(dāng)返回9302時(shí),此時(shí)檢查一下你的密鑰因子是否正確,包括用戶卡序列號(hào),成員銀行及城市代碼,由于密鑰因子錯(cuò)了,分散出的過(guò)程密鑰也是錯(cuò)的,所以計(jì)算出的MAC也是錯(cuò)的
- UART_Send_Enter();
- DisCardfail();
- }
- CLRBuff();
- Request_loop();
- Dis_Deduct_Charge(0);
- continue;
- }
-
-
- UART_Send_Str("用戶卡返回的交易驗(yàn)證TAC:");
- UART_Put_Num(g_cReceBuf,4);
- UART_Send_Enter();
- UART_Send_Str("用戶卡返回的MAC1:");
- UART_Put_Num(&g_cReceBuf[4],4);
- UART_Send_Enter();
-
- memcpy(DataBuf, &g_cReceBuf[4], 4); //拷MAC2,然后發(fā)送給PSAM卡進(jìn)行校驗(yàn)
- st=Credit_SAM_For_Purchase(DataBuf, g_cReceBuf); //MAC2校驗(yàn)//
- if(st!=SAM_OK)
- {
-
- UART_Send_Str("校驗(yàn)MAC2錯(cuò)誤:");
- UART_Put_Num(g_cReceBuf,2); //顯示錯(cuò)誤代碼
- UART_Send_Enter();
- DisCardfail();
- CLRBuff();
- Request_loop();
- Dis_Deduct_Charge(0);
- continue;
- }
-
- UART_Send_Str("扣款MAC2校驗(yàn)成功!");
- UART_Send_Enter();
- UART_Send_Enter();
- st=FM1208_ReadNomey(EP ,g_cReceBuf); //讀充值后的余額//
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
CPU卡定額消費(fèi)帶PSAM卡操作并顯示屏顯示.zip
(222.9 KB, 下載次數(shù): 262)
2018-12-6 18:00 上傳
點(diǎn)擊文件名下載附件
|
|