RFID实验一总结

龙云尧个人博客,转载请注明出处。

CSDN地址:http://blog.csdn.net/michael753951/article/details/70254340

个人blog地址:http://yaoyl.cn/rfidshi-yan-yi-zong-jie-2/


刚接到这个课程项目的时候,是一脸懵逼的。毕竟是第一次接触JavaCard编程(其实就是自己没认真听课)。不过在围观各路大佬的博客之后,总算对整个项目有了较为深入的了解。

在实验过程中,需要不断翻阅实验课PPT之《01 Java智能卡之概述》,《02 电子钱包的文件系统》,《实验2文档》,以及CSDN大佬吕浪的课程总代码,以及他相关博客的Java card开发系列文章。

然后再自己不断重写代码,理解整个实现过程,才能对这个课程实验有较为深入的了解。

代码在未征得本人同意之前,请勿直接Ctrl+C,Ctrl+V,谢谢。

正式实验

实验分析

首先我们要知道本次实验中需要修改哪些函数,实现那哪些功能。

首先我们在PPT最后知道本次实验的主要目的是:

  • 创建文件
  • 写秘钥
  • 读写二进制文件

再看详细内容,我们大概可以捋清如下关系:

  • 创建文件
    • 卡片收到命令并且开始解析
    • 所谓的解析就是判断是何种文件,然后再进行创建
    • 异常处理
  • 写秘钥
    • 秘钥消息是一条一条接受的,每次只会写入一条秘钥
    • 卡片收到命令以后,取出数据,然后写入秘钥文件
  • 读写二进制文件
    • 写指令只需要一条
    • 根据指令内容获得需要的参数,然后将其写入持卡人文件或者应用文件中
    • 注意:写入之前需要检查数据时候超过限定大小
    • 读取和写类似

在有了大概思路以后,我们开始阅读源代码。经过简单寻找,我们发现本次实验涉及的代码大多集中在Purse.java中。

上面四个元素指明了我们将要操作的几个对象。

这个部分似乎用处不明。但是根据让我们填写的部分,可以看出这一块是卡片读取指令的地方,将其缓冲到papdu中,让我们得以进行后续分析。

注释已经说明了,在《01 Java智能卡之概述》P30也有讲到该部分的作用,这里就是我们分析指令的地方,通过这个地方我们可以知道卡片当前接收的指令目的是什么。

将PPT上的操作内容先填进去,具体实现我们待会再说。

我们发现这里还需要添加读二进制的常量。

再往下读,就是创建文件部分。

注释和代码里已经说明,将会有4种文件可以被创建

  • 电子钱包文件(EP_file,这个部分已经给出)
  • 秘钥文件
  • 持卡人基本文件
  • 应用基本文件

剩下的就是圈存指令获取,初始化,以及一些其他操作,不是本次试验需要关心的部分。

开始打码

前面的分析中,我们已经对本次实验有了大致的了解,接下来就是开始打码的过程了。

我们在PPT《01 Java智能卡之概述》中已经知道了cAPDU的结构。

我们也在各种文件中知道了每个参数的意义:

  • CLA,即class,指令的类,占2Bytes
  • INS,instructions,指令编码,占2Bytes
  • P1 - 第一个指令参数,2Bytes
  • P2 - 第二个指令参数 (P1,P2 根据INS不同,也有不同的含义),2Bytes
  • LC,数据段的长度(多少个字节),2Bytes
  • Data部分就是真正的数据了,最长可以是255个字节
  • LE字节表示的是期望卡片发回来的字节长度,注意不包括9000等响应

首先我们完善process。

按照已知的结构,将缓冲中的数据取出来,并且依次按照对应的位置放进papdu中。

因为新加入了数据,所以我们需要更新卡片当前的LE,以便和终端进行确认。

handleEvent函数我们已经按照PPT改好了。接下来就是将它们一个一个实现。

模仿提示的case,根据todo,我们可以列出其他3中情况,分别指向创建密钥文件,持卡人基本文件和应用基本文件。具体的对应条件在实验2文档中有详细说明。

RFID实验一总结_第1张图片

仔细分析EP_file函数,这是一个钱包文件创建的样例,仔细阅读便可以对指令的解析过程有一个深入的了解。

根据上图,我们对EP_file稍作修改,添加了ins校验,keyfile校验,p1p2校验。校验过程中,我们对cAPDU中所有参数进行全部确认一遍,然后确认EPfile目前为空,KEY文件已经建立,我们才能开始进行文件的读写,以免该函数在其他地方被误调用。

仿照这个模式,我们可以很快吧剩下3个文件建立实现出来。

Person_ file和Card_file的实现在这里略过,和EP _file一模一样。Key _file则需要稍加注意。因为Key是最先创建的,所以这个时候,keyfile肯定还是null,所以和其他判定条件不太一样,其他条件一样。

最后就是write_key和write _read _bin的实现了。

观察write_key表中的参数,以及p2的取值。

我们可以类似于之前创建文件的操作,完成写key操作。

再然后就不难了。根据实验2文档,我们可以顺利写完整个代码。

首先是write_read _bin()实现。利用switch进行选择。

以及二进制的读和写操作函数。不过注意的是,写数据的时候,要注意数据data要在[1, 255]之间进行选择,否则会越界(因为LC不够长)。

到这里,整个实验一就结束了。在填写完代码之后整个思绪都变得异常清晰,在操作中使用严格的控制能够良好的避免错误,也能够方便我们整理思路。让我们的撸代码的时候,思路更加清晰。

验证实验

首先将脚本.txt文件转换成.jcsh文件,然后转码成UTF-8,不转码就会出现乱码,eclipse就无法正常读取脚本。

然后在eclipse的控制台输入/set-var path "D:\Eclipse_cpp_workspace\purse",注意文件路径填写的是你的.jcsh脚本文件所在的位置,然后输入你的脚本文件名就行了,如purse_script。(不需要加后缀)

这个时候我们发现,所有指令已经能够no error了。实验一成功了。

2017/4/25 更新

基于验收过程中,跑真机过程中出现0x6B00报错的情况。注释掉了create_file中关于P1参数的检验。注释掉了ins 检验(ins检验其实应该没问题)。可能原因是因为真机中运行时指令和之前给的测试样本中的指令不完全一致,或者在create _file中p1有某种特殊的意义而不一定比为0x00(这部分没有在ppt和word中找到)。

另外,基于这个问题,在Purse.java(Java卡的入口类)编写的时候,不推荐按照我的实现方法进行实现。

你可能感兴趣的:(rfid)