JavaCard应用程序开发三部曲 - 基础篇

2020-12-05 10:25:17 明华物联网

1、什么是智能卡

智能卡不是新鲜事物。它们在二十年前在欧洲就以记忆卡片的形式推出了,用于保存关键的电 话信息,以减少盗打付费电话的可能。

智能卡技术是ISO 国际标准组织的连接技术委员会1(JTC1)和国际电子委员会(IEC)定义并控制的一种行业标准。1987 年推出的 ISO/IEC 7816 国际标准系列在 2003 年推出了它的最新的升级版本,定义了智能卡的各个方面,包括物理特征、物理接触界面、电子信号和传输协议、命令、安全 体系、应用程序标识符和公用数据元素等。

智能卡是一个包含嵌入集成电路(IC)的塑料卡片,类似于一张信用卡。当用作 SIM 卡时,这个塑料卡片很小,正好能放入手机中。智能卡设计时就极注重高度安全性,窜改一点点内容都会导致 毁坏它包含的信息。

在智能卡使用的某些领域,它们只是仅仅提供受保护的非易失性存储。更高级的智能卡还有微 处理器和内存,用于安全的处理和储存,并且可以用于使用公共密钥或者共享密钥算法的安全应用 程序。智能卡上的非易失性存储是最宝贵的资源,可用于保存秘钥和数字证书。一些智能卡有单独的加密协处理器,支持象 RSA、AEC 和(3)DES 这样的算法。

智能卡不包含电池,只有在和读卡机连接的时候才被激活。当它被连接时,在执行一个复位序列之后,卡片处于非激活状态,等待接收来自客户端(主机)应用程序的命令请求。

智能卡可以分为可接触和非可接触。可接触智能卡通过读卡器和智能卡的 8 个触点物理接触来通讯并工作,而非可接触智能卡依靠在小于 2 英尺的一般距离之内的射频信号通讯。非接触智能卡的射频通信基于类似于用于保存反盗窃和记录清单的射频标识符( RFID)标记的技术。图 1 描述了可接触和非可接触智能卡:

明华澳汉物联网

图1a.接触式智能卡

明华澳汉物联网

图 1b.非接触式智能卡

Java Card 技术还存在除了智能卡之外的其它的形态,例如智能按钮和 USB 令牌,这两种如图2 所示。这些的功能和智能卡差不多,例如用于验证用户或者传送敏感信息。智能按钮包含一块电池而且是基于可接触模式,而 USB 令牌则可以直接插入个人计算机的 USB 端口,而不需要任何可接触或者非可接触读卡器。这两种类型的 Java Card 具有与智能卡相同的编程能力并且具有防篡改能力。

明华澳汉物联网

图 2a. 带有 Java 功能的智能纽扣

明华澳汉物联网

图 2b. 带有 Java 功能的 USB 令牌

请参阅 What is a Smart Card?  http://java.sun.com/products/javacard/smartcards.htm获取更详细的信息。

2、JavaCard 规范

多年以前,Sun 微系统公司实现了智能卡和类似的资源约束设备的潜能,并且定义了一组 Java技术子集规范来为它们创建应用程序,Java Card 小应用程序。支持这些规范的设备称为 Java Card平台。在一个 Java Card 平台上,来自不同的供应商的多个应用程序可以安全地共存。

一个典型的 Java Card 设备有一个 8 或 16 位的运行在 3.7MHz 的中央处理器,带有 1K 的 RAM和多于 16K 的非易失性存储器(可编程只读存储器或者闪存)。高性能的智能卡带有单独的处理器和加密芯片,以及用于加密的内存,并且有一些还带有 32 位的中央处理器。

Java Card 技术规范目前是 2.2 版,由三部分组成:

  • Java Card 虚拟机规范,定义了用于智能卡的 Java 程序语言的一个子集和虚拟机。

  • Java Card 运行时环境规范,进一步定义了用于基于 Java 的智能卡的运行期行为。

  • Java Card 应用编程接口规范,定义了用于智能卡应用程序核心框架和扩展 Java 程序包和类。

Sun 还提供了 Java Card 开发工具箱(JCDK)  http://java.sun.com/products/javacard/,包含了Java Card 运行期环境和 Java Card 虚拟机的引用实现,和其它帮助开发 Java Card 小应用程序的工具。本文的第二部分将详细讲述 JCDK。

Java Card 技术和 J2ME 平台

让我们比较一下 Java Card 和 J2ME 平台技术:

明华澳汉物联网

图. Java Card 技术和 J2ME 平台

CDC 和 CLDC 配置以及它们相关的简表是 J2ME 平台的一部分,而 Java Card 是一个单独创建来用于智能卡环境的平台。

3、元素

完整的 Java Card 应用程序由一个后端应用程序和系统、一个主机(卡外)应用程序、一个接口设备(读卡器)和卡上小应用程序、用户证书和支持软件组成。所有的这些元素共同组成一个安全的端到端应用程序:

明华澳汉物联网

图 1. Java Card 应用程序的体系结构

一个典型的 Java Card 应用程序不是孤立的,而是包含卡端、读取端和后端元素。让我们更详细的讲述一下每个元素。

后端应用程序和系统

后端应用程序提供了支持卡上 Java 小应用程序的服务。 例如,一个后端应用程序可以提供到安全系统和卡上的证书的连接,提供强大的安全性。在一个电子付款系统中,后端应用程序可以提供到信用卡及其他付款信息的访问。

读取端主应用程序

主应用程序存在于一个例如个人计算机这样的台式机或者终端、电子付款终端、手机或者一个安全子系统中。

主应用程序处理用户、Java Card 小应用程序和供应商的后端应用程序之间的通讯。

传统的读取端应用程序是使用 C 编写的。近来 J2ME 技术的广泛普及有望使用 Java 实现主应 用程序;例如,它可以在一台支持 MIDP 和安全信赖服务应用编程接口(Security and Trust Services API)手机上运行。

智能卡供应商一般不仅提供开发工具箱,而且提供支持读取端应用程序和 Java Card 小应用程序的 应用程序编程接口。例如 OpenCard Framework  http://www.opencard.org/,就是一个基于 Java 的应用程序编程接口集,隐藏了来自不同供应商的读取器的一些细节,并且提供了 Java Card 远程方法调用分布式对象模型和安全信任服务应用编程接口(SATSA),在本文后面一部分讨论它们。

读取端卡片接受设备

卡片接受设备(CAD)是处于主应用程序和 Java Card 设备之间的接口设备。一个 CAD 为卡片提供电力,以及与之进行电子或者射频通信。一个 CAD 可能是一个使用串行端口附于台式计算机的读卡器,或者可能被整合到终端内,例如饭店或者加油站内的电子付款终端。接口设备从主应用程序到卡片转送应用程序协议数据单元( Application Protocol Data Unit,简称 APDU)命令(在后面讨论),并且从卡片向主应用程序转送响应。一些 CAD 有用于输入个人识别号码的键盘,有的可能还有显示屏。

卡片端小应用程序和环境

Java Card 平台是一个多应用程序环境。在图4中我们可以看到,卡片上可能存在一个或多个Java Card 小应用程序,还有支持软件--卡片的操作系统和 Java Card 运行时环境(JCRE)一起。JCRE 由 Java Card 虚拟机、Java Card Framework 和应用程序编程接口以及一些扩展应用程序编程接口组成。

所有的Java Card小应用程序扩展Applet 基本类,并且必须实现install()和process()方法;JCRE在安装小应用程序的时候调用 install(),并且在每次有一个进入的用于小应用程序的 APDU 的时候调用 process()。

Java Card 小应用程序在被装载的时候实例化,并且在断电的时候保持运行。Java Card 小应用程序起一个服务器的作用,并且是无源的。在一张卡片被加电以后,每个小应用程序都保持非运行的状态直到它被选择,在此时可能会做初始化。小应用程序只有在一个 APDU 被发送给它以后才被激活。一个小应用程序如何激活(被选择)在"一个 Java Card 小应用程序的生命周期"一节中描述。

与 Java Card 小应用程序通讯(访问智能卡)

你可以使用两种模型中的任何一种来在一个主应用程序和一个 Java Card 小应用程序之间通信。第一个模型是基本消息传送模型,第二种是基于 Java Card 远程方法调用(JCRMI),这是 J2SE RMI 分布式对象模型的一个子集。此外,SATSA 通过一个基于更加抽象的应用编程接口的普通连接框架(Generic Connection Framework,简称 GCF)应用编程接口,让你要么使用消息传递要么使用 JCRMI 来访问智能卡。

4、消息传递模型

图 1 中说明的消息传递模型是所有 Java Card 通信的基础。它的核心就是应用程序协议数据单元(APDU),CAD 和 Java Card 框架之间交换的一个逻辑数据包。JavaCard 框架接收任何 CAD发送进来的 APDU 命令并且传送到相应的小应用程序中。小应用程序处理 APDU 命令,然后返回一个响应 APDU。那些 APDU 遵守国际标准规格 ISO/IEC 7816 - 3 和 7816 - 4。

明华澳汉物联网

图 1 使用消息传递模型通讯

读卡器和卡之间的通信通常基于下面两种连接协议的一种,面向字节的 T = 0,或者面向数据块的 T = 1。还可能会用到被称为 T = USB 和 T = RF 的替换协议。JCRE APDU 类向应用程序隐藏了一些协议细节,但不是全部,因为 T = 0 协议相当的复杂。

⒈APDU 命令

一个 APDU 命令的结构由它的第一个字节的值控制,大部分情况下看上去如下所示:

明华澳汉物联网

图 2、APDU 命令

一个 APDU 命令有一个必须有的头和一个可选的体,包含:

  • CLA(1 字节):这个必要的字段识别指令的一个特定应用程序类。有效的 CLA 值在ISO 7816 4 规范中定义:

表格 1、ISO 7816 CLA 值

CLA 值

指令类

0x0n, 0x1nISO 7816 - 4 卡指令,比如文件存取和安全操作
20 to 0x7F保留
0x8n or 0x9n你可以用作你的特定的应用程序指令的 ISO/IEC 7816 - 4 格式,根据标准解释' X '
0xAn特定的应用程序或者供应商的指令
B0 to CF你可以用作特定应用程序的 ISO/IEC 7816 - 4 格式
D0 to FE特定的应用程序或者供应商的指令
FF保留给协议类型选择
  • 理论上,你可以使用所有的 CLA 值 0x80 或者更高值来用于特定应用程序指令,但是在许多 现在的 Java Card 实现中,只有黑体显示的是实际认可的。

  • INS(1 字节):这个必需的字段指明 CLA 字段中标示的指令类中的一个特定指令。ISO 7816 - 4 标准指定用于访问卡上的数据的基本指令,当它根据在像标准中定义的卡上的文件系统那样结构 化的时候。附加功能已经在这个标准中的其它地方说明,其中一些是安全功能。表 2 中是一个 ISO 7816 指令的列表。只有当使用一个相应的 CLA 字节值时,你才可以根据标准定义你自己的特定应 用程序的 INS 值,。

表格 2、当 CLA = 0x 时的 ISO 7816 - 4 INS 值
INS 值命令描述
0EErase Binary
20Verify
70Manage Channel
82External Authenticate
84Get Challenge
88Internal Authenticate
A4Select File
B0Read Binary
B2Read Record(s)
C0Get Response/td>
C2Envelope
CAGet Data
D0Write Binary
D2Write Record
D6Update Binary
DAPut Data
DCUpdate Record
E2Append Record
  • P1(1 字节):这个必需的字段定义指令参数 1。你可以使用这个字段来检验 INS 字段,或者用于输入数据。

  • P2(1 字节):这个必需的字段定义指令参数⒉你可以使用这个字段来检验 INS 字段,或者用于输入数据。

  • Lc(1 字节):这个可选的字段是命令的数据字段的字节数。

  • 数据字段(可变的,字节 Lc 数):这个可选的字段保存命令数据。

  • Le(1 字节):这个可选的字段指定在期望响应的数据字段中的极限字节数。

取决于命令数据的存在与否以及相应是否必须,命令 APDU 有四种变化。只有在你使用协议 T =0 时,你才需要关心这些变化:

明华澳汉物联网

图 3、APDU 命令的四个可能的结构

一个典型的应用程序将以不同的结构方式使用不同的 APDU 命令。

2、响应 APDU

响应 APDU 的格式很简单的:

明华澳汉物联网

图 4、响应 APDU

和一个 APDU 命令相似,响应 APDU 有可选择的和必要的字段:

  • 数据字段(可变长度,由 APDU 命令中的 Le 确定):这个可选择的字段包含小应用程序返回的数据。

  • SW1(1 字节):这个必要的字段是状态字 1。

  • SW2(1 字节):这个必要的字段是状态字 2。

这些状态字的值在 ISO 7816 - 4 规范中定义:

明华澳汉物联网

图 5、响应状态码

Java Card 框架应用编程接口中的 ISO7816 Java 接口定义了许多常数来帮助规范返回错误代码。

3、过程 APDU

每当有一个进入的 APDU 用于所选择的小应用程序,JCRE 就调用小应用程序的 process ()方法,把进入的 APDU 作为一个参数传送。这个小应用程序必须解析 APDU 命令,处理数据、生成一个响应 APDU,然后把控制权返回给 JCRE。

RMI(JCRMI)通讯模型

第二种通信模型依靠 J2SE RMI 分布式对象模型的一个子集。

在 RMI 模型中,一个服务器应用程序创建并生成可访问的远程对象,并且一个客户应用程序获得到远程对象的远程引用,然后调用它们的远程方法。在 JCRMI 中,Java Card 小应用程序是服务器,而主应用程序是客户端。

JCRMI 由类 RMIService 提供到扩展程序包 javacardx.rmi 中。JCRMI 消息被封装到传入RMIService 方法的 APDU 对象中,换句话说,JCRMI 提供了一个基于 APDU 消息传递模型的分布式对象模型机制,通过这个机制服务器和客户端通信,来回传送方法信息、参数和返回值。

5、虚拟机技术

Java Card 虚拟机(JCVM)规范定义了 Java 程序设计语言的一个子集和一个用于智能卡的兼容Java 的虚拟机,包括二进制数据表示和文件格式,以及 JCVM 指令集。

用于 Java Card 平台的虚拟机是两部分实现,一部分在卡外,一部分运行在卡本身。卡上的 JavaCard 虚拟机解释字节码、管理类和对象等等。外部 Java 虚拟机部分是一个开发工具,一般称为 JavaCard 转换工具,装载、检验和进一步地准备卡片小应用程序 Java 类,用于在卡上执行。转换工具输出的是一个 Converted Applet(CAP)文件,这是一个包含一个 Java 程序包中所有类的文件。转换程序检验类是否遵循 Java Card 规范。

JCVM 只支持 Java 程序设计语言的一个有限的子集,然而它保留了许多熟悉的特性,包括对象、继承、程序包、动态对象创建、虚拟方法、接口和异常。JCVM 规范放弃了对许多语言元素的支持,因为这些语言元素可能会用掉很多智能卡本来就很有限的内存:

表格 1、Java Card 语言限制的摘要信息
语言特性动态类装载、安全管理(java.lang.securitymanager)、线程、对象克隆和某些方面的程序包访问控制
 不支持。
关键字不支持 native、synchronized、transient、volatile、strictfp。
类型不支持 char、double、float 和 long,也不支持多维数组。对 int 的支持是可选的。
类和接口不支持除了 Object 和 Throwable 以外的 Java 核心应用编程接口类和接口(java.io、java.lang、java.util),并且 Object 和 Throwable 的大部分方法不可用。
异常一些 Exception 和 Error 子类被省去,因为它们封装的异常和错误不可能在 Java Card 平台上出现。

还有程序模型限制。例如一个装载库类不能再扩展到卡上;它隐含地成为 final 类型。

为了符合存储限制,JCVM 规范额外定义了许多程序属性的约束。表格 4 JCVM 资源限制总结。注意这些约束中许多对于 Java Card 开发者来说是很明白的。

表格 2、Java Card 虚拟机约束的摘要信息
程序包一个程序包可以引用 128 个其他的程序包
一个完全合乎要求的程序包名限于 255 字节以内。 注意字符大小取决于字符编码。
一个完全合乎要求的程序包名限于 255 字节以内。
一个类最多可以直接或者间接地实现 15 个接口。
一个接口最多可以继承于 14 个接口。
一个程序包如果包含小应用程序(一个小应用程序程序包),它最多可以有 256 个静态方法;如果没有小 应用程序(库程序包),它最多只能有 255 个静态方法。
一个类最多可以实现 128 个 public 或者 protected 实例方法。

在 Java Card 虚拟机中,象在 J2SE 虚拟机中一样,class 文件是核心,但是 JCVM 规范定义了两种其他文件格式来进一步使平台独立,转换小应用程序(Converted Applet,CAP)和导出 (Export)格式,这将后面的文章中讲述。

虚拟机的生命周期

JCVM 的生命周期与卡片本身的生命周期一致:在卡片制造并测试之后至发行到持卡人手中的一段时间内它就开始了生命周期,当卡片丢失或者毁坏的时候它的生命周期也就结束了。 卡片没有电力的时候JCVM 也不会停止,因为它的状态被保存在卡片的非易失性存储器中。启动 JCVM 初始化 JCRE 并且创建所有的 JCRE 框架对象,这些在 JCVM 的整个生命周期都是运转着的。JCVM 启动之后,与卡片所有的相互作用原则上都是被卡片上的某个小应用程序控制。 当卡片没电的时候,保存在 RAM 中的任何数据都会丢失,但是保存在永久性存储器中的任何状态都被保留。当再次加电以后,虚拟机又再次激活,这时虚拟机和对象的状态被恢复,并且重新开始执行等待进一步地输入。

6、应用编程接口

Java Card 应用编程接口规范定义了传统的 Java 程序设计语言应用编程接口的一个小的子集--甚至小于 J2ME 的 CLDC。不支持字符串也不支持多线程。没有象 Boolean 和 Integer 这样的包装类,也没有 Class 和 System 类。

除 Java 核心类的小子集以外,Java Card 框架还定义了它自己的特定支持 Java Card 应用程序的核心类。这些包含在下面的程序包中:

  • java.io 定义了一个异常类,基本的 IOException 类,来完成 RMI 异常层次。除此之外,没 有包含其他传统的 java.io 类。

  • java.lang 定义了 Object 和 Throwable 类,但是没有 J2SE 中那么多方法。它还定义了许多 异常类:Exception 基本类,各种运行时间异常和 CardException。除此之外,没有包含其他传统的java.lang 类。

  • java.rmi 定义了 Remote 接口和 RemoteException 类。 除此之外,没有包含其他传统的 java.rmi 类。 对远程方法调用(Remote Method Invocation,RMI)的支持被包含来简化的移植并整合到使用 Java Card 技术的设备中。

  • javacard.framework 定义了组成核心 Java Card 框架的接口,类和异常。 它定义了重要的 概念,例如个人识别号(Personal Identification Number,PIN),应用程序协议数据单元(Application Protocol Data Unit,APDU),Java Card 小应用程序 Applet,Java Card System(JCSystem)和一个 utility 类。 它还定义了各种 ISO7816 常数和各种 Java Card 特定的异常。 表格5总结了这些程序包的内容:

 

Table 5. 表格 Java Card v2.2 javacard.framework
接口ISO7816 定义与 ISO 7816-3 和 ISO 7816-4 相关的常数。
MultiSelectable 识别可以支持并发选择的小应用程序。
个人识别号码(PIN)描述一个被用于安全(验证)目的的个人识别号。
Shareable 识别一个共享对象。能通过小应用程序防火墙的对象必须实现这个接口。
AID 定义了一个遵循 ISO7816-5 与应用程序提供者关联的 Application 标识符;一个小应用程序必备的属性。
&APDU 定义了一个遵循 ISO7816-4 的应用程序协议数据单元,是小应用程序(卡上)和主应用程序(卡外) 之间使用的通信格式。
小应用程序定义了一个 Java Card 应用程序。所有的小应用程序必须扩展这个抽象类。
JCSystem 提供了控制小应用程序生命周期、资源和事务管理,和小应用程序内部对象共享和对象删除的方法。
OwnerPIN 是 PIN 接口的一个实现。
Util 提供用于操作数组和各种 short 的方法,包括 arrayCompare()、arrayCopy()、arrayCopyNonAtomic()、arrayFillNonAtomic()、getShort()、makeShort()、setShort()。
异常定义了各种的 Java Card 虚拟机异常类:APDUException、CardException、CardRuntimeException、ISOException、PINException、SystemException、TransactionException、UserException。

javacard.framework.service 定义了用于服务的接口、类和异常。 服务处理 APDU 格式的进入的命令。 表格 6 总结了框架服务应用编程接口:

表格 6. javacard.framework.service
接口Service,基本的服务接口,定义了 processCommand()、processDataIn()和 processDataOut()方法。
RemoteService 是一个普通 Service,提供到卡上的服务的远程处理。
SecurityService 扩展了 Service 基本接口,并且提供了查询当前安全状况的方法,包括 isAuthenticated ()、isChannelSecure ()和 isCommandSecure ()。
BasicService 是一个服务的默认实现;它提供帮助方法来处理 APDU 和服务协作。
&Dispatcher 维护一个服务的注册。如果你想委托一个 APDU 的处理到几个服务上,你可以使用一个dispatcher。 一个 dispatcher 可以使用 process ()方法完整的处理一个 APDU,或者使用 dispatch ()方法把它发送到几个服务上让其处理。
异常ServiceException 一个服务相关的异常

javacard.security 定义了用于 Java Card 安全框架的类和接口。 Java Card 规范定义了一个强健的安全应用编程接口,包括各种型式的私钥和公钥及其算法、用于计算循环码校验(CRCs)的方法、消息摘要和签名:


表格 7. javacard.security
接口普通的基本接口 Key,PrivateKey、PublicKey 和 SecretKey,以及描述各种类型安全密钥和算法的子接口:AESKey、DESKey、DSAKey、DSAPrivateKey、DSAPublicKey、ECKey、ECPrivateKey、ECPublicKey、RSAPrivateCrtKey、RSAPrivateKey、RSAPublicKey
Checksum:用于循环冗余码校验算法抽象基本类
KeyAgreement:用于秘钥约定算法的基本类
KeyBuilder:秘钥-对象工厂
KeyPair:一个保存一对秘钥的容器,一个私钥一个公钥
MessageDigest:用于散列算法的基本类
RandomData:用于生成随机数的基本类
Signature:用于签名算法的基本抽象类
异常CryptoException:与加密有关异常,比如不支持的算法或者未初始化的秘钥。

javacardx.crypto 是一个扩展程序包,定义了接口 KeyEncryption 和 Cypher 类,都在自己的程序包中,便于控制导出。使用 KeyEncryption 来解密一个使用加密算法的输入秘钥。 Cypher 是所有的密码必须实现的基本抽象类。

CardRemoteObject 定义两个方法 export()和 unexport(),允许或者禁止从卡外到对象的远程访问。RMIService 扩展了 BasicService,并且实现 RemoteService 来处理 RMI 请求。

安全和信任服务应用编程接口(SATSA)

定义在 JSR177 中的 SATSA,指定一个提供用于 J2ME 的安全和信任应用编程接口的可选程序包。客户端应用编程接口提供了到通过一个安全元素(例如一张智能卡)提供的服务的访问,包括敏感信息的安全存储与检索,以及加密和验证服务。

SATSA 利用定义在 CLDC 1.0 版本中的普通连接框架(GCF)来提供到消息传递和 JCRMI 通信模型的更抽象的接口。为了支持信息传送,SATSA 定义了 APDU:URL 模式和 APDUConnection,并且为了支持 JCRMI,它定义了 JCRMI:模式和 JavaCardRMIConnection。

SATSA 有下面的程序包组成:

  • java.rmi 定义了 Java2 标准版 java.rmi 程序包的一个子集,特别是 Remote 和RemoteException。

  • javacard.framework 定义了一个远程方法可能抛出的标准 Java Card 应用编程接口异常:CardRuntimeException、ISOException、APDUException、CardException、PINException、SystemException、TransactionException 和 UserException。

  • javacard.framework.service 定义了远程的方法可能抛出的一个标准的 Java Card 应用编程接口服务异常:ServiceException。

  • javacard.security 定义了一个远程方法可能抛出的标准的 Java Card 应用编程接口与加密相关的异常:CryptoException。

  • javax.microedition.io 定义了两个连接子接口,APDUConnection 用于基于 APDU 协议的智能卡的访问,JavaCardRMIConnection 用于 Java Card RMI 协议。

  • javax.microedition.jcrmi 定义了 Java Card RMI stub 编译程序生成的 stub 使用的类和接口。

  • javax.microedition.pki 定义了用于用户证书基本管理的类。

  • javax.microedition.securityservice 定义了用于生成应用程序级别的数字签名的类。

Java Card 运行时环境

JCRE 规范定义了 Java Card 虚拟机的生命周期,小应用程序生命周期,小应用程序如何被选择并相互隔离,事务和对象持久性和共享。这 JCRE 提供一个平台无关的接口到卡片的操作系统提供的服务。它由 Java Card 虚拟机、Java Card 应用编程接口和任何特定供应商的扩展组成:

明华澳汉物联网

图 Java Card 体系结构和运行时环境

7、小应用程序

Java Card 平台是一个安全的多应用环境-许多来自不同供应商的不同的小应用程序可以在同一张卡片上安全地共存。每个小应用程序被指派给一个执行上下文,这个上下文控制到分配给它的对象的访问。

一个执行上下文和另一个执行上下文之间的界限经常被称为小应用程序防火墙(applet firewall)。它是 Java 沙箱安全概念的一个 Java Card 运行时间改进本,联合类装入器java.ClassLoader 和访问控制器、 java.AccessController 的功能。Java Card 防火墙创建了一个虚拟堆,这样一个对象只能访问存在于相同的防火墙内的(公共的)方法和数据。 一个防火墙可能包含许多小应用程序及其他对象,比如公共的秘钥。一个 Java Card 执行上下文目前作用域是程序包。

当每个对象被创建的时候,它被指派去执行调用程序的上下文。

Java Card 平台支持跨防火墙的安全对象共用。图表 12 描述小应用程序隔离和对象共用:

明华澳汉物联网

图表 1. 小应用程序防火墙和对象共用

典型的流程,如图表 12 中的描述:

请求通过调用系统的JCSystem.getAppletShareableInterfaceObject()方法访问Appletc 的共享接口。

由于Appleta,JCRE 通过调用小应用程序的getShareableInterfaceObject()方法来要求Appletc的可共享的接口。

如果 Appletc 允许共用,Appleta 将获得一个 Appletc 的共享对象的引用。Appleta 现在就可以访问 Appletc 了。 Appleta 将拥有它创建的任意对象,即使是那些定义在 Appletc 的。

在同一个执行上下文中的小应用程序默认情况下能够相互访问,所以 Appleta 和 Appletb 不需要遵循这个程序来共享对象。

管理内存和对象

在一个 Java Card 设备中,内存是最重要的资源。 在一些 Java Card 中,实现一个垃圾收集程序可能不能使用。当一个对象被创建的时候,对象和它的内容被保存在非易失性存储器中,使之可在会话之间使用。在某些情况下,应用程序数据不需要持久- -它是暂时的或者瞬变的(transient)。

为了减少智能卡的持久性内存的消耗,并且最大化它的生命周期,我们要尽可能的经常以 transient更新数据。

Java Card 技术不支持关键字 transient。取而代之,Java Card 应用编程接口(javacard.framework.JCSystem)定义了三个方法,允许你在运行时间创建 transient 数据,还定义了一个方法让你检查一个对象是否是 transient 的:

static byte[] makeTransientByteArray(short length, byte event)

static Object makeTransientObjectArray(short length, byte event)

static short[] makeTransientShortArray(short length, byte event)

static byte isTransient(java.lang.Object theObj)

你可以创建一个瞬变的字节或者 short 基本数据类型的数组,你也可以创建一个瞬变 Object。但是记住下面用于瞬变数据的行为: 

一个瞬变对象的状态在会话之间不能持久保存。 注意内容(不是对象本身)是什么是瞬变的。和任何其他的 Java 语言对象一样,一个瞬变对象只要它被引用就一直存在。

当一个事件例如卡片复位或者小应用程序取消选择发生的时候,一个瞬变对象的内容可能重置为字段的缺省值(0、false 或者 null)。

因为安全的理由,瞬变对象的字段不被保存在持久内存中。

对瞬变对象字段的更新不是原子性的,不会受事务的影响。

在一个 Java Card 环境中,数组和基本类型应在对象声明中声明,并且你应该最小化对象实例化,以利于对象重用。实例化对象在小应用程序生命周期中只有一次,最好在小应用程序的初始化阶段,在小应用程序生命周期中只被调用一次的 install()方法中。

为了促进对象的重用,对象应该保持在小应用程序的生命周期的范围内或引用中,并且它们的 状态(成员变量的值)在重用之前根据情况重置。 因为垃圾收集程序并不总是可用的,一个应用程序可能从不回收分配给不太占用内存的对象的存储器。

持久的事务

JCRE 支持原子事务,原子事务安全地更新一个或多个持久对象。如果发生掉电或者程序错误等情况,事务将保护数据的完整性。 事务是在系统级支持的,通过下面的方法:

JCSystem.beginTransaction()

JCSystem.commitTransaction()

JCSystem.abortTransaction()

在一个为许多事务模型所共用的模式中,一个 Java Card 事务以对 beginTransaction()的调用开始,以对 commitTransaction()或者 abortTransaction()的调用结束。 让我们来看看使用这些应用程序编程接口的代码片断:

...

private short balance;

...

JCSystem.beginTransaction();

balance = (short)(balance + creditAmount);

JCSystem.commitTransaction();

...

实例变量 balance 的更新是为了保证一个原子操作。 如果一个程序错误或者电力重置等事件发生,这个事务就会保证前面的 balance 值余额被恢复。

JCRE 不支持嵌套事务。

8、生存周期

卡片上的每个小应用程序由一个 Application 标识符(AID)唯一标识。 定义在 ISO 7816 - 5中的 AID 是一段 5 到 16 字节之间的序列。 所有的小应用程序必须扩展 Applet 抽象基本类,这个类定义了 JCRE 使用的方法来控制小应用程序的生存周期,如图 10 概括:

明华澳汉物联网

图表 1. Java Card 小应用程序生命周期方法

小应用程序生存周期在小应用程序被下载到卡片中并且 JCRE 调用小应用程序的 static Applet.install ()方法的时候开始,并且小应用程序通过调用 Applet.register ()在 JCRE 中注册。 一旦小应用程序被安装并且注册,它处于未选择的状态,可以进行选择并且处理 APDU。 图表 11.总结小应用程序方法的操作。

明华澳汉物联网

图表 2、使用 Java Card 小应用程序方法

当处在未选择的状态的时候,小应用程序是非激活状态。当主应用程序要求 JCRE 选择一个卡片中特定的小应用程序的时候(通过指示读卡器发送一个SELECT APDU 或者MANAGE CHANNEL APDU),一个小应用程序被选择进行 APDU 处理。为了通知这个小应用程序主应用程序已经选择了它,JCRE 调用它的 select()方法;小应用程序一般执行相应的初始化来为进行 APDU 处理做准备。

一旦选择,JCRE 传送输入的 APDU 命令到小应用程序,通过调用它的 process()方法来进行处理。JCRE 捕捉任何小应用程序没能捕捉的异常。

当主应用程序告诉 JCRE 选择另一个小应用程序的时候,前一个小应用程序取消选择。 JCRE通知活动的小应用程序,它已经通过调用它的 deselect()方法被取消了选择,小应用程序回到不活动的未经选择的状态。

Java Card 会话和逻辑通道

卡片会话是卡片被加电并且和读卡器交换 APDU 的一段时间。

Java Card 2.2 支持逻辑通道(logical channels)的概念,允许最多智能卡中的 16 个应用程序会话同时开启,每个逻辑通道一个会话。因为卡片中的 APDU 的处理不能中断,并且每个 APDU 包含一个到逻辑通道(在 CLA 字节)的引用,变动的 APDU 可以拟同步地访问卡片上的许多小应用程序。你可以设计一个小应用程序被多次选择;也就是说,每次和一个以上逻辑通道通信。多选的小应用程序必须实现 javacard.framework.MultiSelectable 接口和相应方法。

在一些卡片部署中,一个默认小应用程序可以被定义为在卡片复位以后被自动地选择,用于在基本逻辑通道(通路 0)上通信。Java Card 2.2 允许你定义默认小应用程序,但是不指定的如何做;其机理由厂家特定。

首页
产品
动态
联系