CPU卡FM1208发卡操作流程(不带密钥验证)

本文仅记录简单的发卡流程,具体意义请参考相关文档

以下是针对一张新卡而言,如果是旧卡密钥可能就不是FFFFFFFFFFFFFFFF

1、获取随机数(先复位)

         0084000004

2、外部认证:
    获取随机数:
    <- 0084000004
    -> 06CEE4F29000
    加密:(可以使用第三方工具,或者读卡器自带的sdk demo里面的功能得到加密数据)
    06CEE4F200000000 与密钥FFFFFFFFFFFFFFFF进行单倍长DES加密得到FEC63184B307AEFD
    认证:
    <- 0082000008FEC63184B307AEFD
    -> 9000

3、擦除卡片

         800E000000

4、发卡

1)创建应用目录

          80E030010D380080F0F095FFFF4F43415244

2)选择应用

         00A40000023001

3)创建二进制文件

         80E0000307280005F0F0FFFF

4)写入数据

00D60000050102030405

 

5、读取数据

a、复位

b、选择应用3001

         00A40000023001

c、读取数据

       00B0830000

 

 

参考:

1https://www.jianshu.com/p/ff9145a49d58

2https://blog.csdn.net/weixin_42381351/article/details/81746595

3https://www.jianshu.com/p/bb2c461a4d6b

4fmcos用户手册

  • 0
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的使用C语言编写的FM1208 CPU发卡和读的代码示例,其中使用了串口通信和APDU指令: ```c #include <stdio.h> #include <string.h> #include <stdlib.h> #include <termios.h> #include <fcntl.h> #include <unistd.h> #define MAX_BUF_LEN 1024 int serialOpen(char *port, int baudrate) { int fd; struct termios newtio; fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY); if (fd < 0) { perror("open"); return -1; } tcgetattr(fd, &newtio); memset(&newtio, 0, sizeof(newtio)); newtio.c_cflag = baudrate | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; newtio.c_lflag = 0; newtio.c_cc[VTIME] = 0; newtio.c_cc[VMIN] = 1; tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &newtio); return fd; } void serialClose(int fd) { close(fd); } int sendAPDU(int fd, unsigned char *apdu, int apduLen, unsigned char *respBuf, int *respLen) { unsigned char buf[MAX_BUF_LEN]; int len; write(fd, apdu, apduLen); len = read(fd, buf, MAX_BUF_LEN); memcpy(respBuf, buf, len); *respLen = len; return 0; } int main(int argc, char **argv) { int fd; unsigned char apdu[256] = {0}; unsigned char respBuf[MAX_BUF_LEN] = {0}; int respLen = 0; // 打开串口 fd = serialOpen("/dev/ttyS0", B9600); if (fd < 0) { printf("open serial port failed\n"); return -1; } // 发送APDU指令 // 发卡 apdu[0] = 0x00; apdu[1] = 0xA4; apdu[2] = 0x04; apdu[3] = 0x00; apdu[4] = 0x08; apdu[5] = 0xA0; apdu[6] = 0x00; apdu[7] = 0x00; apdu[8] = 0x00; apdu[9] = 0x03; apdu[10] = 0xF0; apdu[11] = 0x01; apdu[12] = 0x01; apdu[13] = 0x05; sendAPDU(fd, apdu, 14, respBuf, &respLen); memset(apdu, 0, sizeof(apdu)); memset(respBuf, 0, sizeof(respBuf)); respLen = 0; // 读 apdu[0] = 0x00; apdu[1] = 0xB0; apdu[2] = 0x00; apdu[3] = 0x00; apdu[4] = 0x08; sendAPDU(fd, apdu, 5, respBuf, &respLen); // 处理片响应 if (respBuf[respLen - 2] == 0x90 && respBuf[respLen - 1] == 0x00) { printf("Read card success\n"); } else { printf("Read card failed\n"); } // 关闭串口 serialClose(fd); return 0; } ``` 需要注意的是,上述代码仅供参考,具体的代码实现需要根据所使用的硬件平台和应用场景进行相应的调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值