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中。

基本元素

上面四個元素指明瞭我們將要操作的幾個對象。

process

這個部分似乎用處不明。但是根據讓我們填寫的部分,可以看出這一塊是卡片讀取指令的地方,將其緩衝到papdu中,讓我們得以進行後續分析。

handleEvent

註釋已經說明了,在《01 Java智能卡之概述》P30也有講到該部分的作用,這裏就是我們分析指令的地方,通過這個地方我們可以知道卡片當前接收的指令目的是什麼。

將PPT上的操作內容先填進去,具體實現我們待會再說。

handleEventv1

添加INS_READ_BIN

我們發現這裏還需要添加讀二進制的常量。

再往下讀,就是創建文件部分。

create_file

註釋和代碼裏已經說明,將會有4種文件可以被創建

  • 電子錢包文件(EP_file,這個部分已經給出)
  • 祕鑰文件
  • 持卡人基本文件
  • 應用基本文件

剩下的就是圈存指令獲取,初始化,以及一些其他操作,不是本次試驗需要關心的部分。

開始打碼

前面的分析中,我們已經對本次實驗有了大致的瞭解,接下來就是開始打碼的過程了。

我們在PPT《01 Java智能卡之概述》中已經知道了cAPDU的結構。

cAPDU結構

我們也在各種文件中知道了每個參數的意義:

  • CLA,即class,指令的類,佔2Bytes
  • INS,instructions,指令編碼,佔2Bytes
  • P1 - 第一個指令參數,2Bytes
  • P2 - 第二個指令參數 (P1,P2 根據INS不同,也有不同的含義),2Bytes
  • LC,數據段的長度(多少個字節),2Bytes
  • Data部分就是真正的數據了,最長可以是255個字節
  • LE字節表示的是期望卡片發回來的字節長度,注意不包括9000等響應

首先我們完善process。

processv1part1

按照已知的結構,將緩衝中的數據取出來,並且依次按照對應的位置放進papdu中。

processv1part2

因爲新加入了數據,所以我們需要更新卡片當前的LE,以便和終端進行確認。

handleEvent函數我們已經按照PPT改好了。接下來就是將它們一個一個實現。

create_filev1

模仿提示的case,根據todo,我們可以列出其他3中情況,分別指向創建密鑰文件,持卡人基本文件和應用基本文件。具體的對應條件在實驗2文檔中有詳細說明。

文件類型

仔細分析EP_file函數,這是一個錢包文件創建的樣例,仔細閱讀便可以對指令的解析過程有一個深入的瞭解。

create_file_table

根據上圖,我們對EP_file稍作修改,添加了ins校驗,keyfile校驗,p1p2校驗。校驗過程中,我們對cAPDU中所有參數進行全部確認一遍,然後確認EPfile目前爲空,KEY文件已經建立,我們才能開始進行文件的讀寫,以免該函數在其他地方被誤調用。

EP_file

仿照這個模式,我們可以很快吧剩下3個文件建立實現出來。

Person_ file和Card_file的實現在這裏略過,和EP _file一模一樣。Key _file則需要稍加註意。因爲Key是最先創建的,所以這個時候,keyfile肯定還是null,所以和其他判定條件不太一樣,其他條件一樣。

Key_file

最後就是write_key和write _read _bin的實現了。

觀察write_key表中的參數,以及p2的取值。

p2

write_key_table

我們可以類似於之前創建文件的操作,完成寫key操作。

write_key

再然後就不難了。根據實驗2文檔,我們可以順利寫完整個代碼。

首先是write_read _bin()實現。利用switch進行選擇。

write_read_bin

以及二進制的讀和寫操作函數。不過注意的是,寫數據的時候,要注意數據data要在[1, 255]之間進行選擇,否則會越界(因爲LC不夠長)。

write_binary

read_binary

到這裏,整個實驗一就結束了。在填寫完代碼之後整個思緒都變得異常清晰,在操作中使用嚴格的控制能夠良好的避免錯誤,也能夠方便我們整理思路。讓我們的擼代碼的時候,思路更加清晰。

驗證實驗

首先將腳本.txt文件轉換成.jcsh文件,然後轉碼成UTF-8,不轉碼就會出現亂碼,eclipse就無法正常讀取腳本。

然後在eclipse的控制檯輸入/set-var path "D:\Eclipse_cpp_workspace\purse",注意文件路徑填寫的是你的.jcsh腳本文件所在的位置,然後輸入你的腳本文件名就行了,如purse_script。(不需要加後綴)

run_part1

run_part2

這個時候我們發現,所有指令已經能夠no error了。實驗一成功了。

2017/4/25 更新

基於驗收過程中,跑真機過程中出現0x6B00報錯的情況。註釋掉了create_file中關於P1參數的檢驗。註釋掉了ins 檢驗(ins檢驗其實應該沒問題)。可能原因是因爲真機中運行時指令和之前給的測試樣本中的指令不完全一致,或者在create _file中p1有某種特殊的意義而不一定比爲0x00(這部分沒有在ppt和word中找到)。

另外,基於這個問題,在Purse.java(Java卡的入口類)編寫的時候,不推薦按照我的實現方法進行實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章