第 2部分 JAVA 卡技術
第 3章 Java卡技術概述
Java卡技術能夠使利用 Java 程式設計語言寫的程式在智慧卡上和其它資源有限的裝置上運行。
本章將對 Java 卡技術-系統體繫結構及其組成部分作一概括描述。
3.1 體繫結構概述
智慧卡代表現今使用的最小的計算平台。智慧卡的儲存空間配置例如可以是:1K RAM, 16K
EEPROM, 和 24K ROM。Java 卡技術設計的最大挑戰是:要把 Java 系統軟體放到智慧卡上,
同時還要為應用保留足夠的空間。解決這個問題的辦法是只支援 Java 語言特性的子集和採用分
離模式的 Java 虛擬機器。
Java 卡虛擬機器被分割成兩個部分:一部分運行於卡外,而另一部分運行於卡上。許多不限於
運行時執行的處理任務,例如類的 loading,位元組碼驗證,地址確定與連結,以及最佳化等,由於運
行於卡外的虛擬機器來處理,在那裡資源通常不必關心。
智慧卡在許多方面不同於台式電腦。除了支援Java語言外,Java 卡技術還定義了一個運行
時環境,這個環境支援智慧卡儲存空間、通訊、安全,和應用執行模式。Java 卡運行時環境符合智
能卡國際標準 ISO 7816。
Java卡運行環境的最重要的特性就是把智慧卡作業系統和應用清晰地分離開來。運行環境將
底層的複雜性和智慧卡系統的細節封裝起來。應用通過清晰定義的進階編程介面請求系統服務和
資源。
因此,Java 卡技術實質上乃定義了這樣一個平台:在這個平台上,用Java程式設計語言寫的應用
能夠在智慧卡中和其它資源有限的裝置上運行。(為 Java 卡平台寫的應用稱為 applets.)。因為分
離的虛擬機器體繫結構,該平台從時空角度,乃分佈於智慧卡和台式機之間。Java 卡技術由三個部
分組成,各於一個規範中定義。
z Java 卡 2.1 虛擬機器 (JCVM) 規範:定義 Java 程式設計語言子集和適合於智慧卡應用
的虛擬機器定義。
z Java 卡運行時環境(JCRE)規範:精確地描述了Java 卡的運行時行為, 包括儲存管理、
applet管理,和其它運行時特性。
z Java 卡 2.1 應用編程介面(API) 規範:描述了編程 Java 卡應用的核心與擴充 Java 包
和類。
3.2 Java 卡語言子集
因為它的儲存空間之小,Java 卡平台只能支援Java語言特性的一個經過精心挑選的、定製的
子集。 這個子集包括的特性非常適合為智慧卡和其它小型裝置編寫的程式,而卻保持了 Java 編
程語言的物件導向的能力。表3.1 著重給出了某些重要的支援的和不支援的 Java 語言特性。
把那些不支援的特性的 keywords 也省略了,這是不足為怪的。許多進階的 Java 卡提供垃
圾收集機制,使對象刪除成為可能。
附錄 A 提供了 Java 卡語言子集的詳盡注釋。關於需要儲存和操作大數的 Java 卡 applets,
14章提供了在不使用大的基礎資料型別 (Elementary Data Type)的前提下處理大數的編程提示。
表 3.1 支援的和不止持的Java 特性
Supported Java Features Unsupported Java Features
• 小的基礎資料型別 (Elementary Data Type): boolean,byte, short
•一維數組
•Java包, 類,介面, 和例外
• Java 物件導向的特性:繼承,虛擬機器,重載和
動態資料對象建立,訪問域,以及約束規則
• int keyword 和32-位bit 整數資料類型支援
是任選的。
• 大的基礎資料型別 (Elementary Data Type): long,double, float
• 字元和字串
• 多維陣列
• 動態類裝載
•安全管理器
• 垃圾收集和 finalization
• 線程
• 對象序列化
•對象cloning
3.3 Java 卡虛擬機器
Java 卡虛擬機器(JCVM) 和Java虛擬機器(JVM)之間的一個主要差別在於JCVM 是作為兩個分立
的部分實現的,3.1所示。Java 卡虛擬機器的卡上部分包括 Java 卡位元組碼解譯器。而 Java 卡
轉換器運行於PC或工作站。轉換器是虛擬機器的卡外部分。卡上和卡外部分一起實現了虛擬機器的全
部功能,包
圖 3.1 Java 卡虛擬機器
括 loading Java 類檔案和按特定的語意執行之。轉換器裝載與預先處理構成 Java 包的類檔案和輸
出 CAP (converted applet) 檔案。而後將 CAP 檔案裝載到 Java 智慧卡中並有解譯器執行。除了
建立 CAP 檔案之外,轉換器還產生一個表示正北轉換的包的公用 APIs 的輸出檔案。
Java 卡技術只支援Java 語言的子集。相應地,Java 卡虛擬機器也只支援那些由該語言子集需
要的特性。轉換器將刪除那些在 applet 中使用的不支援的語言特性。
3.3.1 CAP 檔案和 Export 檔案
Java 卡技術引入兩種新的二進位檔案格式,它們使 Java 卡軟體平台無關地進行開發、發布
和執行。一個 CAP檔案包含一個Java包中的類的可執行檔二進位表示。JAR 檔案格式用作 CAP
檔案的 container 格式。一個 CAP 檔案對應一個包含其諸成分集合的 JAR 檔案,每個成分為該
JAR 檔案中的一個檔案。每個成分描述CAP檔案內容的一個方面,例如類資訊、可執行檔位元組碼、
連結資訊、驗證資訊,等等。CAP 檔案的格式是針對小型化的裝置,利用緊縮的資料結構和有限
的間接而被最佳化了。它定義了一個位元組碼指令集,該指令集基於 Java 位元組碼指令集,並對其進
行了最佳化。
Java 程式的 “寫一次,到處運行” 的品性或許是 Jav 平台的最重要特性。在 Java 技術中,
類檔案是 Java 體繫結構的中心部分,它定義了 java 平台二進位相容性的標準。因為 Java 卡系
統體繫結構的分布式特點,CAP 檔案建立了關於 Java 卡平台的二進位相容性的標準檔案格式。
CAP 檔案格式就是把軟體裝載到 java 卡上的形式。例如,CAP 檔案能夠在卡片做好之後,動
態地裝載 applet 類。 這就是其得名 CAP (converted apple) 檔案的原因所在。
Export 檔案不被裝載到智慧卡上並且不被解譯器直接使用,而它們是由轉換器產生並用於驗
證和連結過程。可將 Export 檔案視為C程式設計語言中的標頭檔。一個 export 檔案包含一個包的公
共的 API。它定義類的訪問域(scope)與名字和方法的訪問域與簽名,以及類的域(fields)。
一個 export 檔案還包含用於卡上包間的 resolving 的連結資訊。
export 檔案不包含任何關於實現的資訊,即不含位元組碼。所以,一個 export 檔案可由applet
開發人員自由發布給該 applet 的潛在使用者,而不會泄露內部實現細節。
3.3.2 Java 卡 轉換器(Converter)
不像 Java 虛擬機器(一次處理一個類),轉換器的轉換單位是一個包。編譯器由原始碼產生
類檔案,而後轉換器預先處理構成一個 java 包的全部類檔案,並將這個包轉換為一個 CAP 檔案。
在轉換過程中,轉換器執行案頭環境下Java虛擬機器在裝載類時所完成的任務:
z 驗證Java類的裝載映像格式無誤
z 檢查Java卡語言子集是否違例
z 完成靜態變數的初始化
z 將對類、方法和域的符號引用解析為可在卡上有效處理的更緊湊的形式
z 利用在類裝載與連結時獲得的資訊最佳化位元組碼
z 分配儲存空間和建立表示類的虛擬機器資料結構
轉換器不僅把類檔案作為轉換的輸入,輸入還可能包括一或多個 export 檔案。除了產生一
個 CAP 檔案外,轉換器還產生一個關於被轉換包的 export 檔案。圖 3.2 表明一個包是如何被
轉換的。轉換器裝載一個Java包中的全部類。如果該包輸入來自其它包的類,轉換器還將裝載這
些包的 export 檔案。轉換器的輸出是一個CAP 檔案和一個正被轉換的包的 export 檔案。
圖 3.2 轉換一個包
3.3.3 Java 卡 解譯器(Interpreter)
Java 卡解譯器提供 Java 語言模型的運行時支援,因此允許 applet 代碼與硬體無關。解譯器
執行下列任務:
z 執行位元組碼指令並最終執行 applets
z 控制儲存分配和對象建立
z 在保證運行時安全中扮演重要角色
至此,Java 卡虛擬機器已經被描述為由轉換器和解譯器組成。然而,在我們目前的定義中非正
式地把 Java 卡虛擬機器被定義為該虛擬機器的卡上部分――解譯器。這一習慣已經用於許多早期的
Java卡出版物中。因此,本書後面的部分將會同時使用“Java 卡解譯器”和“Java 卡虛擬機器”這
兩個詞,除非另外說明。但是,在比較 Java 卡平台和 Java 平台時,讀者應知道執行 Java 類文
件的功能是由轉換器和解譯器二者一起完成的。
3.4 Java 卡 Installer 和卡外安裝程式
Java 卡解譯器本身並不裝載 CAP 檔案,它只執行在 CAP 檔案中發現的代碼。在 Java 卡
技術中,下載和安裝 CAP 檔案的機制乃包含在一個稱為安裝器(installer)的組件中。
Java 卡安裝器駐留在卡片中,它與卡外的一個安裝程式協同工作。該卡外安裝程式通過卡片
接收裝置(CAD),將CAP檔案中的可執行檔二進位代碼傳送給在卡上啟動並執行安裝器。安裝器把二
進位代碼寫入智慧卡儲存空間中,將其與已經放在卡片上的其它類進行連結,並建立和初始化由Java
卡運行時環境內部使用的任何資料結構。安裝器和安裝程式以及它們如何與 Java 卡平台的其餘
部分相關聯示於圖3.3。
解譯器和CAP檔案安裝器間功能的拆分使得解譯器保持較小,並且提供安裝器實現的靈活性。
關於安裝器的更多的解釋在本章後頭的 applet 安裝中給出。
PC或工作站
圖 3.3 Java 卡安裝器和卡外安裝程式
3.5 Java 卡運行時環境
Java 卡運行時環境(JCRE) 由運行於智慧卡中的一些 Java 卡系統組件構成。 JCRE 負責卡
片資源管理、網路通訊、applet 執行,和卡上系統與 applet 的安全。因此,它實際上充當智慧卡
作業系統的角色。
3.4所示,JCRE 位於智慧卡硬體和 native 系統的頂上。JCRE 由 Java 卡虛擬機器(位元組碼
解譯器)、Java 卡應用架構類(APIs)、業界專用擴充,以及一些 JCRE 系統類別組成。JCRE 很好地
將 applets 和智慧卡廠商的專用技術隔離開來,並為 applets 提供標準的系統和API 介面。因此,
applets 很容易寫和在各種不同的智慧卡體繫結構上移植。
JCRE 的底層包含Java 卡虛擬機器(JCVM)和一些 native 方法。 JCVM 執行位元組碼、控制存
儲器分配、管理對象,和保證執行的安全性,如前所述。native 方法提供對 JCVM 和上層系統
類的支援。它們負責處理低級通訊協定、儲存管理、cryptographic 支援等。
Applets
JCRE
智慧卡硬體和Native 系統
優惠應用 錢包應用 認證應用
業界專用擴充 安裝程式 架構類(APIs)
Applet 管理 事物管理 I/O網路通訊 其它服務
Java 卡虛擬機器
(位元組碼解釋程式)
Native 方法
圖 3.4 卡上系統的體繫結構
系統類別作為 JCRE 執行程式。這些類是對作業系統核心的類比。系統類別負責管理事物、管理
host 應用1
和 Java 卡 applets 之間的通訊,以及控制 applet 的建立、選擇,和 deselection。為
了完成這些任務,系統類別一般地要調用 native 方法。
Java 卡應用架構定義了應用編程介面。這個架構由四個核心 API 包和一個擴充 API 包組
成。這些 API 類是很緊湊的,並且是專門為開發智慧卡 applets 而定製的。 該架構的主要優點
在於使得一個 applet 的建立變得容易了。於是,applet 開發人員的主要精力可其集中在其 applet
的細節上,而不是智慧卡系統基礎設施的細節上。Applets 通過API 類訪問 JCRE 的服務。
各行業可以提供擴充庫,以提供附加的服務或改善安全和系統模型。例如,Open Platform 擴
展了JCRE 的服務,以滿足金融界專門的安全要求。在許多追加的特性中,強制了發卡行對卡片
的控制並規定了卡片個人化的標準命令集。
卡上安裝程式能夠保證在卡片生產完畢並發行給持卡人之後,軟體和 applets 能夠安全地下
載到卡片中。卡上安裝程式和卡外安裝程式協同操作,它們共同完成 CAP 檔案的二進位內容的
下載任務。卡上安裝程式是一個任選的 JCRE 組成部分。在沒有卡上安裝程式的時候,所有的卡
片軟體(包括applets)都必須在卡片製造過程中寫到卡片的儲存空間中。
Java 卡 applets 是 Java卡平台上的使用者程式。當然,applets 是利用 Java 程式設計語言的的子集
編寫的,並由 JCRE 進行控制和管理。Applets 可在 Java 智慧卡製造好之後再載入到卡上。
3.5.1 JCRE 生命週期
在PC或工作站中,Java 虛擬機器是作為一個作業系統進程啟動並執行。資料和對象被建立於 RAM
之中。當該 OS 進程被終止的時候,Java 應用及其對象被自動地廢棄。
在Java 智慧卡中,Java 卡虛擬機器在Java卡運行時環境中運行。JCRE 於卡片初始化時被初始
化。在整個卡片生命期中,JCRE 僅被初始化一次。在這個過程中,JCRE 初始化虛擬機器並建立
提供 JCRE 服務和管理 applets 的對象。在安裝 applers 的時候,JCRE 建立 applet 執行個體,而
applets 建立儲存資料的對象。
智慧卡上的大多數資訊即使在卡片斷電的時候都必須被保留下來。我們可利用永久儲存空間技
術(例如EEPROM)來實現這一保持資料的目的。資料和對象被建立於永久儲存空間中。JCRE 的
生命期相當於整個卡片的生命期。當去電的時候,虛擬機器只是被掛起。JCRE 和在卡片上建立的
對象的狀態則被保留下來。
下次卡片上電的時候,JCRE 通過從永久儲存空間2
裝載資料而重新啟動虛擬機器執行。這裡一
個微妙的概念是 JCRE 並非恰好從掉電時的斷點來繼續虛擬機器的操作。而是虛擬機器被複位,並從
主迴圈的開頭執行。JCRE 複位與初始化不同,因為它要保留在卡片上建立的 applets 和對象。
在複位期間,如果某個事物在之前未完成,JCRE 將進行任何必要的清楚工作,使JCRE 呈一致
的狀態。
3.5.2 在一個 CAD Session 中 JCRE如何工作?
從卡片插入卡片接受裝置(CAD)並加電至卡片從 CAD 拔出的時間段稱為一個 CAD 會話期
(session)。在 CAD 會話期中,JCRE 像普通智慧卡一樣地操作—它支援與 host 應用的 APDU
I/O 通訊(圖 3.5).。APDUs (應用協議資料單位)是在 applets 和 host 應用之間交換的資料包。每
一個 APDU 或者包含從 host 至 applet 的命令或者從 applet 至 host 的響應。
在 JCRE 複位之後,JCRE 便進入一個迴圈,等待來自 host 的 APDU 命令。 host 通過卡
片的輸入/輸出觸點提供的串列通訊介面向 Java 卡平台發送 APDU 命令。
圖 3.5 APDU I/O 通訊
當一條命令到來的時候,JCRE 或者按照該命令的指示,選擇一個 applet ,或者將接收到的
命令繼續交給當前已經被選擇的 applet。而後,被選擇的 applet 取得控制,並處理該 APDU 命
令。
在結束的時候,該 applet 向 host 應用發送響應並把控制交還給JCRE。在下一條命令到來的
時候,又重複這一過程。Applets 如何處理 APDUs 將於第7和第 8 章中予以說明。
3.5.3 Java 卡運行時特性
除了支援 Java 語言的運行時模式之外,JCRE 還支援三種附加的運行時特性:
z 永久和臨時對象—按預設,Java 卡對象是永久的並被建立於永久儲存空間中。這種對象的
空間與資料跨 CAD 會話期。因為安全性與效能的原因,applets 也可在 RAM 中建立
對象,這樣的對象稱為臨時對象。臨時對象包含非永久的,不跨 CAD 會話期的臨時數
據。
z 原子操作與事物— Java 卡虛擬機器保證每次向一個對象或類中的一個域的寫操作是原子
的。被修改的域或者取得新值或者被恢複為原先的值。另外,JCRE 還提關於供事物的
APIs。 Applet 可將若干寫操作置於一個事物之中。要麼一個事物中的全部修改都被完成,
要麼(如果在該事物當中發生錯誤)什麼都不作。
z Applet防火牆與共用機制 — applet 防火牆將各 applets 隔離開來。每個 applet 運行於一
個指定的空間之內。 一個 applet 的存在與操作對卡片上其它 applets 不會有影響。 applet
防火牆在 Java 卡虛擬機器執行位元組碼的時候被強制。在 applets 需要共用資料或訪問
JCRE 服務的場合,虛擬機器通過安全的共用機制來滿足這些功能。
3.6 Java 卡APIs
Java 卡 APIs 是由一些為根據 ISO 7816 模式編程智慧卡應用而定製的類組成的。APIs 包
含三個核心包和一個擴充包。三個核心包是:java.lang、javacard.framework,和
javacard.security。擴充包是javacardx.crypto。
熟悉 Java 平台的開發人員會注意到許多 Java 平台的類在 Java 卡 APIs 中並不被支援。例
如,Java 平台的關於 GUI 介面、網路 I/O,和 台式機檔案系統 I/O 的類並不被支援。其原因
在於智慧卡沒有顯示器,並且它們使用不同的網路通訊協定以及檔案系統結構。另外,也不支援許多
Java平台的公用程式類,以滿足特定的儲存空間需求。
在 Java 卡 APIs 中的類是緊湊而簡明的。它們包括一些為了提供 Java 語言支援和密碼技
術服務而根據 Java 平台改編的類。它們還包括一些為支援智慧卡 ISO 7816 標準而專門建立的
類。
3.6.1.java.lang 包
Java 卡的 java.lang 包是其 Java 平台上的對應包 java.langpackage 的嚴格子集。該包所支
持的類是 Object, Throwable,和某些與機器有關的例外類,如表 3.2 所示。對於所支援的類,
許多 Java 方法是不能用的。例如,Java 卡 Object 類 只定義了預設的構造方法和 equals 方
法。
java.lang 包提供基本的 Java 語言支援。類 Object 為 Java 卡類階層定義了一個根,
而類 Throwable 為所有的例外提供了一個共同的祖先。所支援的例外類保證在由於 Java 語言
違例而導致錯誤發生時有一致性的語意。例如,當訪問一個Null 參考時,Java 虛擬機器和 Java 卡虛
擬機都拋出一個 NullPointerException 例外。
Table 3.2 Java 卡java.lang 包
Object Throwable Exception
RuntimeException ArithmeticException ArrayIndexOutOfBoundsException
ArrayStoreException ClassCastException IndexOutOfBoundsException
NullPointerException SecurityException NegativeArraySizeException
3.6.2.javacard.framework 包
javacard.framework 是一個重要的包。 它為 Java 卡 applet 的核心功能提供了架構類和
介面。最重要的是它定義了一個基礎 Applet 類,後者為 applet 的執行和其生命期內與 JCRE 的
互動提供了一個架構。它在面對 JCRE 所扮演的角色方面,類似於 Applet 類面對 host 瀏覽器
時的角色。一個使用者 applet 類必須從基類 Applet 擴充而來,並且重寫 Applet 類中的方法以實
現該 applet 的功能。
javacard.framework 包中的另一個重要的類是 APDU 類。APDUs 由傳輸協議傳送。兩個
標準的傳輸協議是 T=0 和 T=1。 APDU 類設計得與傳輸協議無關。換言之,它是被精心設計
的,從而使 applet 的開發人員感覺不到 T=0 和 T=1 協議的複雜性以及它們之間的差異。Applet
開發人員可利用 APDU 類中提供的方法極其容易地處理 APDU 命令。不管平台支援的底層傳輸
協議為何,Applets 都能正確地工作。在第 8 章中將說明如何使用 APDU 類。
Java卡平台不支援 Java 平台的類 java.lang.System 。 Java 卡平台包含一個提供與系統效能
相關的介面類 javacard.framework.JCSystem 。JCSystem 類包括控制 applet 執行、資源管
理、事物管理,以及 Java 卡平台上 applet 間對象共用的方法集。
javacard.framework 包中支援的其它類是 PIN,公用程式,和例外。PIN 是個人識別碼
(personal identification number)的簡稱。它是為了認證持卡人而在智慧卡中使用的最普通的口令
形式。
3.6.3.javacard.security 包
javacard.security 包 提供關於Java卡平台上支援的密碼功能的架構。它的設計基於包
java.security。
javacard.security 包 定義了一個密鑰工廠類 keyBuilder 和描述用於對稱(DES)或非對稱
(DSA 和 RSA)演算法中的密碼技術密鑰的各種介面。此外,它還支援抽象的基類 RandomData、
Signature,和 MessageDigest,後者用於產生隨機數資料和計算報文摘要與簽名。
3.6.4.javacardx.crypto 包
javacardx.crypto 包是一個擴充包。它包含受制於美國出口條例要求的密碼技術類和介面。
javacardx.crypto 包定義關於支援加密和解密功能的抽象基類 Cipher 。
包 javacard.security 和 javacardx.crypto 定義 applets 調用請求密碼技術服務的 API
介面。然而,它們並未提供任何實現。一個 JCRE 提供者需要提供這些密鑰介面的類並繼承抽
象類 RandomData, Signature, MessageDigest,和 Cipher。通常,卡片上有一個獨立的副處理器
來完成密碼技術有關計算。第10章將解釋如何利用包 javacard.security 和 javacardx.crypto
中的類支援 applets 中的密碼技術功能。
3.7 Java 卡Applets
不要就因為 Java 卡 applets 和 Java applets 名字都叫 applet,而將二者相混淆。一個 Java
卡 applet 是一個要遵守一組約束的 Java 程式,只允許它運行於 Java 卡運行時環境中。一個
Java 卡 applet 不會在一個瀏覽器環境中運行。為 Java 卡應用取名 applet 的原因在於在卡片已
經製造好之後,仍能夠將 Java 卡 applets 裝載到 Java 卡運行時環境中。即,不像在許多嵌入式
系統中那樣,不需要在製造階段將 applets 燒到ROM中。而是,在以後的某時刻,能將它們動態
地下載到卡片中。
一個 applet 類必須從 javacard.framework.Applet 類擴充而來。基類 Applet 是駐留在
Java卡中的所有 applets 的超類。這個 applet 類是定義一個 applet 中的變數和方法的模板。一個
正在卡片上啟動並執行 applet 是一個 Applet 執行個體 — 該 applet 類的一個對象。像任何永久對象一
樣,一個 applet 執行個體一旦被建立,它就會永久存活在卡片上。Java 卡運行時環境支援多應用環
境。多個 applets 能夠並存於同一張 Java 智慧卡上,並且一個 applet 可建有多個執行個體。例如,
可建立一個錢包 applet 執行個體支援美元, 而建立另一個執行個體支援英鎊。
3.8 包和Applet 命名規範
你所熟悉的 Java 平台中的包和程式是利用 Unicode 串和基於 Internet 網域名稱的命名方案來
唯一標識的。然而,在 Java 卡平台中,每個 applet 執行個體是通過應用標識符(AID)來唯一標識
和選擇的。另外,每個 Java 包也被賦予一個 AID 。當把封裝載到卡片上的時候,便通過它們
的AID將其與卡片上的其它包連結起來。
ISO 7816 規定了用於唯一標識卡片的應用和卡片檔案系統中某些類型域的APIs。一個 AID
是一個位元組數組,可被解釋為兩個不同的部分, 3.6 所示。第一部分是一個 5 位元組的值,
稱為 RID (源標識符)。第二部分是一個可變長度的值,稱為 PIX (專用標識符擴充)。 PIX 的長
度可從 0 到 11 位元組。因此,一個 AID 總長可從 5 到 16 位元組。
RID (5 bytes) PIX (0–11 bytes)
圖 3.6 應用標識符 (AID)
ISO 控制給公司 的 RIDs 分配;每個公司有一個唯一的 RID。 公司自己管理AIDs中的
PIXs 的分配。本節只對 AIDs 進行簡要地描述。關於全部細節,請參見 ISO 7816-5,AID 註冊
分類 D 的格式。
在 Java 卡平台中,一個包的 AID 是通過該公司的 RID 和這個包的 PIX 的連結而構成的。
一個 applet 的 AID 是以和包 AID 類似的方法而構造的。它是該 applet 提供者的 RID 和該
applet 的 PIX 的連結。一個 applet 的 AID 一定不要用和任何包的 AID 或任何其它 applets 的
AID 相同的值。然而,由於一個 AID中的 RID 標識 applet 提供者,包 AID 及在該包中定義的
applets 的 AID(s) 必須具有相同的 RID。包 AID 和在該包中定義的每個 applet 的預設 applet
AID 在 CAP 檔案中指出。在產生 CAP 檔案時,將它們提供給轉換程式。
3.9 Applet 下載過程
Java 卡 applet 的開發和任何其它 Java 程式一樣而開始。開發人員編寫一個或多個 Java 類
並用某 Java 編譯器編譯原始碼,產生一個或多個 class 檔案。圖 3.7 示範了applet 的開發過程。
接著,在類比環境中運行、測試,和調試該 applet。模擬器在 PC 或工作站上類比 Java 卡
運行時環境。在類比環境中,applet 於 Java 虛擬機器上運行,並因此而執行該 applet 的 class 文
件。通過這種方法,模擬器能夠利用許多 Java 開發工具(虛擬機器、debugger, 和其它工具)並允許
開發人員
圖 3.7 Applet 的開發過程
測試 applet 的行為和快速觀看 applet 的執行結果,而不用經曆轉換過程。在這一步中, applet 的
整個功能方面得以測試。然而,某些 Java 卡虛擬機器運行時特性,例如 applet 防火牆以及對象的
臨時與永久行為,則不能被檢查。
而後,通過 Java 卡轉換程式將構成一個Java包的 applets 的 class 檔案被轉換為一個 CAP
檔案。Java 卡轉換程式的輸入不僅有被轉換的 class 檔案,還有一個或多個 export 檔案。在轉
換該 applet 包的時候,轉換程式還為這個包產生一個 export 檔案。 一個 CAP 檔案或一個 export
檔案代表一個 Java 包。如果一個 applet 由若干包組成,那麼為每一個包建立一個 CAP 檔案和
一個 export 檔案。
在下一步中,將代表該 applet 的 CAP 檔案(可能不止一個)裝載到一個模擬環境中並在該
環境中進行測試。模擬器也在一台 PC 或工作站上類比 Java 卡運行時環境。然而,模擬器是一
個更為複雜的測試載入器。它包含一個 Java 卡虛擬機器 的實現。Applet 在模擬器中的執行行為應和
運行於實際卡片中的行為是一樣的。在這一開發階段,不僅 applet 得以進一步測試, 而且該 applet
的運行時行為也得到測試。
大多數 Java 卡模擬器和模擬器都帶有偵錯工具(debugger)。該偵錯工具允許開發人員設定斷
點或逐步執行程式、觀看在該類比或模擬的 Java 卡運行時環境中的 applet 修改後的執行狀態。
最後,當 applet 被測試後並準備好被下載到實際的卡片中的時候,該 applet(由一個或若干
的 CAP 檔案代表)便被裝載和安裝到 Java 智慧卡中。
3.10 Applet 安裝
在製造 Java 智慧卡的時候, 該智慧卡的專用系統及其運行時環境(包括本地(native)方
法、Java 卡虛擬機器、API 類,以及庫)都被燒到 ROM 中。這個將一些固定的成分寫到晶片的
不易變的儲存空間的過程稱為掩模(masking)。掩模技術是智慧卡廠商的專用工藝技術,本書不再
進一步討論。
3.10.1 ROM Applets
在卡片製造過程中,Java 卡 applet 類可以和 JCRE 及其它系統成分一起掩模到 ROM 中。
在 JCRE 初始化期間或以後某一時刻,由 JCRE 將 Applet 執行個體執行個體化到 EEPROM 中。這樣的
一些 applets 稱為 ROM applets。
ROM applets 是預設的 applets ,由卡片發行者提供,隨卡一起提交。由於 ROM applet 的
內容由發行商控制,Java 卡 工藝技術允許 ROM applets 聲明本地(native)方法,這些方法的
實現是利用別的程式設計語言(例如 C 或彙編代碼)寫的。本地方法不受由卡片虛擬機器強制的安全
檢測。.
3.10.2 事前或事後發行 Applets
另外,在卡片製造之後,Java 卡 applet 的類和相關的類庫也能夠被下載或寫到 Java 智慧卡
的可變儲存空間(例如 EEPROM)中。這樣的 applets 可進一步分類為事前發行或事後發行的
applets。事前和事後這兩個詞是根據 applets 是在卡片發行之前或之後下載的事實而確定的。事
前發行的 applets 按 ROM applets 相同的方式處置,二者都由發卡方控制。
和 ROM applets 或事前發行的 applets 不同,事後發行的 applets 不允許聲明本地方法。原
因在於 JCRE 沒有辦法控制該 applet 的內容。允許被下載的 applets 包含本地代碼會有損於
Java 卡的安全性。以下幾節將集中於事後發行的 applet 的安裝。通常,事前發行的 applets 是
利用和事後發行的applets相同的機制裝載的,但是 Java 卡技術把決定權留給卡片發行者。
3.10.3 事後發行的 Applet 的安裝
Applet 安裝指的是將 applet 類裝載到一個 CAP 檔案中、將這些類和 Java 卡運行時環境的
執行狀態相結合,以及建立一個 applet 執行個體,從而使該 applet 成為能被選擇執行的狀態的過程。
在 Java 卡平台上,裝載和可安裝的單位是一個 CAP 檔案。一個 CAP 檔案由構成一個 Java
包的類組成。一個最小的 applet 就是一個只具有一個從 javacard.framework.Applet 類繼承的類
的包。一個具有很多類的更複雜的 applet 可被組織成一個或一組 Java 包。
為了裝載一個 applet,卡外安裝程式將 CAP 檔案作為輸入並將其轉換為 APDU 命令序列,
該命令序列攜帶該 CAP 檔案的內容。通過和卡外安裝程式交換 APDU 命令,卡上安裝程式把
該 CAP 檔案的內容寫到卡片的永久儲存空間中,並將該 CAP 檔案中的類與駐留在卡片上的其它
類相連結。該安裝程式還建立和初始化任何由 JCRE 內部用於支援 applet 的資料。如果該 applet
需要若干包運行,要把每個相應的 CAP 檔案都裝載到卡片上。
作為 applet 安裝的最後一步,安裝程式建立一個 applet 執行個體並將這個執行個體向 JCRE3
註冊。
為了做到這一點,安裝程式調用 install 方法:
public static void install(byte[] bArray, short offset, byte length);
install 方法是一個 applet 進入點方法,類似於一個 Java 應用中的 main 方法。一個 applet 必
須實現 install 方法。在 install 方法中,它調用 applet 的構造方法以建立和初始化 applet 執行個體。
install 方法的 bArray 參數提供關於 applet 初始化的安裝參數。這些安裝參數隨 CAP 檔案一起
發送給卡片。applet 開發人員定義安裝參數的內容和格式。
在 applet 被初始化並向 JCRE 註冊之後, 它便可被選擇運行。 JCRE 利用AID (應用標識符)
標識一個正在啟動並執行 applet。applet 可利用在 CAP 檔案中找到的預設 AID,或者另選擇一個不
同的 AID 向 JCRE 註冊自己。可利用安裝參數提供一個另外的 AID。
install 方法可被調用多次,以建立多個 applet 執行個體。每個 applet 執行個體都由一個唯一的AID
標識。在 Java 卡環境中,一個 applet 可在不知道如何裝入它的類的情況下而編寫和執行。在安
裝過程中,一個 applet 的唯一責任就是實現 install 方法。
3.10.4.Applet 安裝期間的錯誤恢複
安裝過程是事務性的。在發生錯誤的情況下,例如程式性故障、運行範圍超出儲存空間大小、
卡片拔出,或者其它錯誤,安裝程式都要拋棄該 CAP 檔案和在安裝過程中它已經建立的任何
applet 並恢複空間和 JCRE 的以前狀態。
3.10.5. 安裝限制
讀者應當知道 applet 安裝是不同於運行時動態類裝載的,後者是在台式機環境中的 Java虛
擬機上被支援的。Java 卡 applet 安裝只意味著在卡片已經製造好之後通過安裝過程下載類的過
程。
因此,Java 卡 applet 安裝有兩個細節。第一,運行於卡片上的 applets 僅指已經存在於卡
片上的類,由於在 applet 代碼正常執行期間沒有辦法下載類。
第二, 裝載的次序必須保證: 每個被新裝入的包只引用已經在卡上的包。 例如, 對於一個 applet
來說,javacard.framework 包必須在卡片中, 因為所有的 applet 類都必須從類
javacard.framework.Applet 擴充而來。 如果存在包 A 和包 B 循環參考情況, 安裝過程將失敗。