Java Card Applet Development——環境搭建及基礎概念(JCDK v2.2.2&v3.0.0.5)

本文改編自:http://www.dreamingfish123.info/?p=580,旨在對原文進行擴展,對JCDK v3.0.0.5的情況進行說明。

JAVA CARD技術基本概念

Java Card是基於硬件與應用的要求所開發的技術,目的是使得Java技術能夠再如同smart card芯片般大小的有限資源下執行,是能運行Java程序的智能卡。Java Card技術提供了一種開放式開發構架,現在的智能卡開發者可以開發出在多種智能卡上應用的程序,不同的應用程序可以在同一個卡片上運行。

從一個 applet 的編寫、編譯、轉換、部署、使用的過程看,會是這樣的與腳本相關的過程:

  1. javac – 編譯 *.java
  2. converter – 生成 cap, jca, exp
  3. genscript – 由 cap 文件產生 scr 腳本
  4. apdutool – 利用 scr 腳本,將 applet 部署到卡(虛擬機的 eeprom文件)中
  5. apdutool – 利用虛擬機測試 applet

JAVA CARD DEVELOPMENT TOOLS

目前Oracle已經提供了所有開發Java Card Applet所需要的tools、libraries和一系列的APIs,最多使用的是2.2.1和2.2.2版本。

Note: 目前還不需要用到JCDK 3.x,因爲還沒有實體java卡支持其開發,而在沒有可以實時部署和測試的環境的情況下,去學習這個版本試沒有意義的。

JCDK中包含Converter、APDUTool、ScriptGen等重要的工具,還提供兩個Java智能卡運行環境的仿真工具Cref和JCWDE,通過這兩個工具,無需讀/寫器和智能卡卡片,開發人員可以在PC軟件平臺上模擬Java智能卡的運行,進行Applet的調試運行。


JAVA CARD APPLET STRUCTURE

幾個比較重要的functions:

public static void install(byte[] bArray, short bOffset, byte bLength){}
public void process(APDU apdu){}
protected final void register(){}
//or protected final void register(byte[] bArray, short bOffset, byte bLength){} throws SystemException public boolean select(){}

  • install( ):構建了Applet子類的實例,JCRE將會最先調用這個;所有的初始化和分配內存的操作應該在這個裏面實現;可以獲取卡外實體傳進來的一些應用初始化參數。
  • process( ):類似於正常java class的main,在安裝後,APDU的執行將在這裏實現。
  • register( ):applet用來在JCRE中註冊該applet實例。
  • register(parameters):和register( )功能一樣,增加了可以分配其特定的AID的功能。
  • select( ):JCRE一旦接收到SELECT[by name]命令時,將尋找命令中指示的AID對應的Applet,使之處於活躍狀態,接收並處理接下來的APDU命令;在選擇新的Applet前,JCRE先調用當前Applet的 deselect 方法;Applet可以拒絕被選擇,此時 select 方法返回false;SELECT[by name]命令本身也將傳遞給applet處理,此時通過 selectingApplet 用以判斷當前狀態。

ECLIPSEJCDE

開發環境搭建

  1. 在Sun/Oracle官網上下載 Java Platform 1.5(JDK) (http://www.oracle.com/technetwork/java/javase/downloads/index.html)
  2. 在Sun/Oracle官網上下載 Java Card Development Kit v2.2.2 (JCDK)(http://www.oracle.com/technetwork/java/javame/javacard/download/devkit/index.html),解壓到 “java-card-dev-kit-root”,例如“C:\java_card_kit-2_2_2”
  3. 解壓“java-card-dev-kit-root/java_card_kit-2_2_2/java_card_kit-2_2_2-rr-bin-windows-do.zip”到“java-card-dev-kit-home”,例如“C:\java_card_kit-2_2_2-windows\java_card_kit-2_2_2”
  4. 下載eclipse 4.3 (http://www.eclipse.org/downloads/),將其內容解壓到“eclipse-root”,例如“C:\eclipse”
  5. 下載EclipseJCDE(http://sourceforge.net/projects/eclipse-jcde/files/),將其內容解壓到“eclipse-root”
  6. 啓動eclipse
  7. 菜單欄中“Java Card” => “Preferences”
  8. 點擊“Browse”,指向“java-card-dev-kit-home”路徑
注意:JCDK v3.0.0.5中不需要進行第5步下載SDK,官網上下載的SDK包已經包含了eclipse 插件(目錄爲:Java Card Development Kit 3.0.5u1\eclipse-plugin) ,直接可以使用eclipse進行安裝。

Tools

  1. “Set Package AID”:設定選中包的AID,這個AID將會在生成CAP文件和APDU腳本、以及將該包安裝到模擬器中時用到。
  2. “Set Applet AID”:設定選中的Java Card Applet的AID
  3. “Convert”:將Java Card package轉換爲CAP文件;可以選擇是否同時生成EXP文件和JCA文件。
    • CAP文件:轉化後的applet文件,可被JAVA卡裝載並安裝的可執行代碼
    • EXP文件:輸出文件,包含JAVA卡包的公共信息和連接信息
    • JCA文件:可讀彙編語言,由轉換器生成,可進一步生成CAP文件
  4. “Generate Script”:生成APDU腳本文件*.script
  5. “Run Script”:發送APDU腳本文件中的APDU命令到模擬器中。

模擬器

  1. “CREF”:是一個C語言實現的參考JCRE的模擬器,但不支持Java Card應用運行在debug模式。
  2. “JCWDE”:Java Card Workstation Development Environment,是另一個模擬器,其支持Java Card應用運行在debug模式下。它是一個模擬了JCRE的java應用,但少了其中一些特徵。

驗證

EclipseJCDE提供了一組編譯時驗證,當Java Card應用程序在安裝或運行在模擬器上時驗證Java卡項目的一致性,避免運行時錯誤。

EclipseJCDE提供以下的驗證:

  1. “Applet AID validation”:檢查所有Java卡項目中的Java Card applet是否都有applet AID。
  2. “Package AID validation”:檢查所有Java卡項目中的包是否都有package AID。
  3. “Duplicate AID validation”:檢查所有Java卡項目以防有重複的AID。

開發實例-HELLOWORLD

Applet實現功能:將所有發送給此Applet的命令原封不動的返回給卡外應用。

該sample以CREF作爲模擬器,用兩種方法實現整個開發流程:Eclipse+JCDE 和 CMD

  • Eclipse+JCDE是利用Eclipse上添加JCDE插件以便於Applet開發。
  • CMD即所有compiling、converting等過程都在命令行下進行,可以在沒有IDE的情況下完成Applet的開發。需要預先設置好環境變量
注意:eclipse中運行模擬器環境時不要點擊右鍵-->Run As-->Java Card Projec運行,這樣運行沒有啓動正確的模擬器,
應該點擊右鍵-->Run As --> Run Configurations,設置如下圖所示,點擊run運行。



例如javacard_env.bat

1
2
3
4
5
@echo off
set JC_HOME=C:\java_card_kit-2_2_2-windows\java_card_kit-2_2_2
set JAVA_HOME=C:\jdk1.5.0_22
set PATH=.;%JC_HOME%\bin;%JAVA_HOME%\bin;%PATH%
set CLASSPATH=%JC_HOME%\lib\api.jar;%CLASSPATH%

Note:jdk的路徑最好不要有空格,默認是裝到”program files”目錄下,這就有空格,會導致後面一些命令出錯。

Compiling

編譯sample applet中的java源代碼:

  • Eclipse+JCDE: 若Project – Build Automatically爲選中狀態,則此時源代碼已經編譯好。
  • CMD:
    1
    javac -g HelloWorld.java

Converting

轉換class文件,生成 .cap, .exp, .jca文件,其中 .cap 文件是實際加載安裝到java card中的文件。

  • Eclipse+JCDE: 在該sample的Java Card Tools中有很多工具,先Set Applet AID爲一串5-16字節長度的序列,例如:0xa0:0×0:0×0:0×0:0×62:0×3:0×1:0xc:0×1:0×1;再Set Package AID,例如:0xa0:0×0:0×0:0×0:0×62:0×3:0×1:0xc:0×1;接着Convert,即可。
  • CMD: 新建一個配置文件HelloWorld.opt
    1
    2
    3
    4
    5
    6
    -out EXP JCA CAP
    -exportpath E:\HUI\java_card\java_card_kit-2_2_2-windows\java_card_kit-2_2_2\api_export_files
    -classdir E:\HUI\java_card\HelloWorld\bin
    -applet  0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1:0x1 com.sun.javacard.samples.HelloWorld.HelloWorld
    com.sun.javacard.samples.HelloWorld
    0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1 1.0

    再在CMD中輸入命令:

    1
    converter -config E:\HUI\java_card\HelloWorld\src\HelloWorld.opt

Note:

  1. 若Eclipse convert時出現error:com.sun.javacard.samples.Helloworld.Helloworld:unsurport class format of version 51.0即想要convert的class文件是爲Java 1.7生成的,但這在JCDK2.2.2中不支持。所以在該project的Properties裏,Java Compiler中設置compiler compliance level爲1.5(jcdk 2.2.2對應支持的jdk版本爲1.5)
  2. AID的格式:| RID(5 bytes) | PIX(0-11 bytes) |
    • 在一個Exp文件中的任何package中必須有一個唯一的AID,此AID對應於包名,如com.sun.javacard.samples.HelloWorld
    • 每一個包中的Applet子類都應該擁有唯一的AID,此AID不可以和任何package的或者其他Applet的AID相同,若一個CAP文件中含有多個Applet子類,那麼這些子類的AID應該有同一個RID。

Running scriptgen

用scriptgen工具生成apdutool所需要的腳本文件*.scr,腳本文件中是一序列的APDU,可以被送進java card中以安裝特定的CAP文件。

  • Eclipse+JCDE: 點選Java Card Tools中的Generate Script,即生成select-HelloWorld.script、cap-download.script、create-HelloWorld.script 三個腳本文件。
  • CMD: 輸入命令:
    1
    scriptgen -o E:\HUI\java_card\HelloWorld\bin\com\sun\javacard\samples\HelloWorld\javacard\HelloWorld.scr E:\HUI\java_card\HelloWorld\bin\com\sun\javacard\samples\HelloWorld\javacard\HelloWorld.cap

    可以得到HelloWorld.scr,但是scriptgen所產生的.scr還需要加上頭尾的.scr纔是完整的.scr(for download to CREF),所以需要在該腳本文件頭尾加上:

1
2
3
4
5
6
7
8
9
10
11
// Power up
powerup;
// Select the installer applet
0x00 0xA4 0x04 0x00 0x09 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x08 0x01 0x7F;
// the
// body
// part
// of
// HelloWorld.src
// Power down
powerdown;

其中cap-download.script = 加上頭尾後的HelloWorld.scr

Note

script file的內容可分爲4個部分:

  1. powerup, install and download .CAP
  2. create and select applet
  3. user testing apdu command
  4. powerdown

其中scriptgen所產生的.scr文件只有第一部分的download .CAP部分,其餘部分需要自行加入。

*第一部分必須在文件頭自行加上:

1
2
3
4
powerup;
// Select the installer applet
0x00 0xA4 0x04 0x00 0x09 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x08 0x01 0x7F;
// 90 00 = SW_NO_ERROR

目的是讓Java卡Power up之後,並選擇了installer applet,再由installer applet將所需要download到卡上的 .cap 文件進行download.

*第二部分必須加上:

1
2
3
4
5
6
// create Test applet(AID需自行填入)
echo "Create Test Applet:";
0x80 0xB8 0x00 0x00 0x0c 0x0a 0xA0 0x00 0x00 0x00 0x62 0x03 0x01 0xc 0x01 0x01 0x00 0x7F;
// Select Applet AID(AID需與create applet 相同)
echo "Select Test Applet:";
0x00 0xa4 0x04 0x00 11 0xA0 0x00 0x00 0x02 0x83 0x00 0x00 0x08 0x12 0x00 0x03 0x7F;

其中create applet的APDU格式爲:

| 0x8x, 0xb8, 0×00, 0×00 | Lc field | AID length field | AID field | parameter length field | [parameters] | Le field |

select applet的APDU格式爲:

| 0x0x, 0xa4, 0×04, 0×00 | Lc field | Installer AID | Le field |

*第三部分則根據applet之所需執行的apdu command由user自行定義並加入

*第四部分則必須在文檔最後加入:

1
powerdown;

APDUTool-Downloading the CAP file

利用 cap-download.script / HelloWorld.scr 腳本,將 applet 部署到卡(虛擬機的 eeprom文件)中

  • Eclipse+JCDE: 點選菜單欄中CREF裏的Start,在之前生成的 cap-download.script 文件右擊下拉欄中點選Java Card Tools中的Run Script
  • CMD: 打開一個命令提示符窗口,調用Cref工具爲HelloWorld程序創建一個內存映像文件HelloWorldImage:
    1
    cref -o HelloWorldImage

    再打開一個命令提示符窗口,執行:

    1
    apdutool E:\HUI\java_card\HelloWorld\bin\com\sun\javacard\samples\HelloWorld\javacard\HelloWorld.scr

    運行結果:

    Java Card 2.2.2 APDU Tool, Version 1.3
    Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Opening connection to localhost on port 9025.Connected.
    Received ATR = 0x3b 0xf0 0×11 0×00 0xff 0×01
    CLA: 00, INS: a4, P1: 04, P2: 00, Lc: 09, a0, 00, 00, 00, 62, 03, 01, 08, 01, Le: 00, SW1: 90, SW2: 00
    CLA: 80, INS: b0, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 90, SW2: 00
    ***此處省略部分結果
    CLA: 80, INS: b4, P1: 09, P2: 00, Lc: 16, 09, 00, 13, 00, 03, 0e, 26, 2b, 00, 0c, 05, 0c, 06, 04, 08, 05, 11, 0c, 07, 09, 06, 09, Le: 00, SW1: 90, SW2: 00
    CLA: 80, INS: bc, P1: 09, P2: 00, Lc: 00, Le: 00, SW1: 90, SW2: 00
    CLA: 80, INS: ba, P1: 00, P2: 00, Lc: 00, Le: 00, SW1: 90, SW2: 00

    由運行結果可見SW1=90,SW2=00,意味着在Cref中已經正確安裝了Java Card Applet。

    在運行Cref命令窗口的當前工作目錄中會發現生成了一個新文件HelloWorldImage。這個文件就是通過APDUTool下載到Cref環境中的內存鏡像文件。

    APDUTool-Create An Applet Instance

    • Eclipse+JCDE:新建一個腳本文件test_HelloWorld.script,將cap-download.script中內容先複製進去,接下來在 powerdown; 的前面,即
    1
    2
    // CAP end
    0x80 0xBA 0x00 0x00 0x00 0x7F;

    後面添加一段APDU命令:

    1
    2
    3
    4
    5
    6
    // Create HelloWorld
    0x80 0xB8 0x00 0x00 0x0c 0x0a 0xA0 0x00 0x00 0x00 0x62 0x03 0x01 0xc 0x01 0x01 0x00 0x7F;
    // Select HelloWorld
    0x00 0xA4 0x04 0x00 10 0xA0 0x00 0x00 0x00 0x62 0x03 0x01 0xc 0x01 0x01 0x7F;
    // Sending the testing APDU command, and the received data should be echo from the whole APDU command
    0x00 0xFF 0x00 0x00 0x0b 'H' 'e' 'l' 'l' 'o' ' ' 'W' 'o' 'r' 'l' 'd' 0x7F;

    從eclipse的Console中可以看到運行結果:

    //前面部分和APDUTool-Downloading the CAP file中的運行結果相同。
    CLA: 80, INS: b8, P1: 00, P2: 00, Lc: 0c, 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 01, 01, 00, Le: 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 01, 01, SW1: 90, SW2: 00
    CLA: 00, INS: a4, P1: 04, P2: 00, Lc: 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 01, 01, Le: 0f, 00, a4,
    04, 00, 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 01, 01, SW1: 90, SW2: 00
    CLA: 00, INS: ff, P1: 00, P2: 00, Lc: 0b, 48, 65, 6c, 6c, 6f, 20, 57, 6f, 72, 6c, 64, Le: 10, 00,
    ff, 00, 00, 0b, 48, 65, 6c, 6c, 6f, 20, 57, 6f, 72, 6c, 64, SW1: 90, SW2: 00
    

    可以看到SW1=90且SW2=00,同時最後測試APDU的datac(即Lc後部分)爲“Hello World”字符串,Applet相應的字串datae(即Le後部分)爲整個輸入的APDU command。

    所以測試成功。

    • CMD: 在運行Cref命令窗口中,執行
      1
      cref -i HelloWorldImage

      這個命令使得當前窗口處於阻塞狀態,直到有APDU命令請求到來。在 E:\HUI\java_card\HelloWorld\bin\com\sun\jav
      acard\samples\HelloWorld\javacard\ 目錄下建立 test_HelloWorld.scr:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // Power up
    powerup;
    // Create the applet
    0x80 0xB8 0x00 0x00 0x0b 0x0a 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x0c 0x01 0x01 0x7F;
    // Select the applet
    0x00 0xa4 0x04 0x00 0x0a 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x0c 0x01 0x01 0x7F;
    // User APDU command 1
    0x80 0x50 0x00 0x00 0x0b 0x01 0x00 0x00 0x00 0x02 0x01 0x02 0x03 0x04 0x05 0x06 0x7F;
    // User APDU command 2
    0x80 0x52 0x00 0x00 0x0b 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0xa0 0x83 0xd0 0x43 0x7F;
    // User APDU command 3
    0x80 0x50 0x01 0x00 0x0b 0x03 0x00 0x00 0x00 0x05 0x01 0x02 0x03 0x04 0x05 0x06 0x7F;
    // User APDU command 4
    0x80 0x54 0x00 0x00 0x0F 0x01 0x02 0x03 0x04 0x04 0x03 0x02 0x01 0x03 0x02 0x01 0x01 0x02 0x03 0x04 0x7F;
    // Power down
    powerdown;

    在APDUTool命令窗口,執行APDUTool命令:

    1
    apdutool E:\HUI\java_card\HelloWorld\bin\com\sun\javacard\samples\HelloWorld\javacard\test_HelloWorld.scr

    將測試腳本文件作爲參數,執行結果直接輸出到命令窗口中。此時Cref命令窗口中的執行結果:

    Java Card 2.2.2 APDU Tool, Version 1.3
    Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms.
    Opening connection to localhost on port 9025.
    Connected.
    Received ATR = 0x3b 0xf0 0×11 0×00 0xff 0×01
    CLA: 80, INS: b8, P1: 00, P2: 00, Lc: 0b, 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 01, 01, Le: 0a, a0,
    00, 00, 00, 62, 03, 01, 0c, 01, 01, SW1: 90, SW2: 00
    CLA: 00, INS: a4, P1: 04, P2: 00, Lc: 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 01, 01, Le: 0f, 00, a4,
    04, 00, 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 01, 01, SW1: 90, SW2: 00
    CLA: 80, INS: 50, P1: 00, P2: 00, Lc: 0b, 01, 00, 00, 00, 02, 01, 02, 03, 04, 05, 06, Le: 10, 80,
    50, 00, 00, 0b, 01, 00, 00, 00, 02, 01, 02, 03, 04, 05, 06, SW1: 90, SW2: 00
    CLA: 80, INS: 52, P1: 00, P2: 00, Lc: 0b, 01, 02, 03, 04, 05, 06, 07, a0, 83, d0, 43, Le: 10, 80,
    52, 00, 00, 0b, 01, 02, 03, 04, 05, 06, 07, a0, 83, d0, 43, SW1: 90, SW2: 00
    CLA: 80, INS: 50, P1: 01, P2: 00, Lc: 0b, 03, 00, 00, 00, 05, 01, 02, 03, 04, 05, 06, Le: 10, 80,
    50, 01, 00, 0b, 03, 00, 00, 00, 05, 01, 02, 03, 04, 05, 06, SW1: 90, SW2: 00
    CLA: 80, INS: 54, P1: 00, P2: 00, Lc: 0f, 01, 02, 03, 04, 04, 03, 02, 01, 03, 02, 01, 01, 02, 03,
    04, Le: 14, 80, 54, 00, 00, 0f, 01, 02, 03, 04, 04, 03, 02, 01, 03, 02, 01, 01, 02, 03, 04, SW1:
    90, SW2: 00

    從測試結果可以看到:SW1=90,SW2=00,說明測試沒有問題。

    Note

    1. 若在Run Script的時候出現error:java.net.ConnectException: Connection refused: connect則需要先將CREF-Start後再Run Script。
    2. 測試腳本中的APDU命令具體可以查閱ISO7816在測試腳本中,以 User APDU Command 1 爲例:
      • 0×80 – CLA:命令報文的類別字節
      • 0×50 – INS:命令報文的指令字節
      • 0×00 – P1:參數1
      • 0×00 – P2:參數2
      • 0x0B – Lc:數據域字節數
      • 0×01 0×00 0×00 0×00 0×02 0×01 0×02 0×03 0×04 0×05 0×06 – 命令報文的數據域
      • 0x7F – Le:響應數據的最大期望長度

    總結

    1. eclipse是免費的IDE,JCDE是開源的插件,提供了便捷但是也有一定的限制。相較而言直接用命令行依賴少,可以用腳本實現高效。建議eclipse只是作爲編寫源代碼的IDE,實際applet的其他過程都通過CMD來實現。
    2. 本例是在虛擬卡環境下運行的,和實際卡的下載安裝等可能會有出入。
    3. 市面上比較流行的Java卡多數都有嵌入在Eclipse環境中的Plug-in,供Java卡開發者集成使用,比如針對Jcop(這是IBM公司的一個團隊基於NXP芯片開發的Java卡平臺,後來授權給NXP公司),在Eclipse環境中安裝全新的Feature後,就可以非常方便地進行仿真和調試。所以可以在對實際Java卡進行開發時再安裝相應的廠商提供的插件或工具等。
    4. 若需要在*nux環境下進行開發,則需相應的下載linux版本的JCDK。

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