副标题#e#
摘要:
从本文开始,我们连续登载一系列在智能卡长举办Java开拓的文章,以此把智能卡向您作一个根基的先容。只要有一块智能卡、一个读卡机和一套可与智能卡通信的软件,你就可以开始举办实用应用措施的开拓了。本文先容的内容包罗:遵循ISO7816尺度的智能卡打点软件;如何利用Gemplus阅读器和Gemplus智能卡从智能卡中读写内存;一些操作智能卡的存储成果的应用措施。今后的文章将先容差异厂家出产的智能卡,而且还将涉及智能卡的尺度。
作为专题系列的第一篇,本文将主要为今后的接头作一个铺垫事情。在此,我们将接头一个称为OpenCard的新尺度。今后的文章将涉及安详智能卡和电子钱包。最后,我们将向您先容智能卡软件的根基框架布局。
无论是在四月份的JavaOne大会上(与该技能有关的四次演讲),照旧在庞大的网络新闻站或是CNN,智能卡掀起了轩然大波。在本文里,我们将以实用智能卡实例向您展示真正的智能卡。这里的技能将答允你开拓智能卡Java应用措施。
我们的接头核心主要会合在两种智能卡之上:存储智能卡,它可以被看作带有可选安详级此外小型可读写磁盘;处理惩罚器卡,它可以被看作带有一个输入输出端口的迷你型计较机。今后的文章将更为深入的先容处理惩罚器卡。
本文的英华之处在于,我们将为读写智能卡创建一个简朴的原形。我们要接头一种医药处方卡,它将替你生存所有的药方清单,并查抄保险、处方打算等等有用的信息。而且我们将环绕处方卡扩展开去。
在这一系列的文章之中,你会留意到陪伴智能卡的一个常见主题,那就是安详性问题。这里所说的安详,主要是防备通过卡的滥插入或ActiveX组件等手段犯科获取数据。为此目标,本文中关于读写智能卡中数据的典型将给你提供一个安详、一致且具可移植性的存储。
智能卡是什么
你可以把智能卡看成一个带有大脑的信用卡。其大脑就是一个小的嵌入式计较机芯片。这种芯片可以被编程执行某项任务或是存储一些数据,但应时刻紧记:该种芯片只不外是小型的,它的处理惩罚本领绝比拟不上你的桌面计较机。
今朝,智能卡仅仅用于电话、运输、银行和保健等行业,可是感激浩瀚的开拓者,在不久的未来,我们就会看到智能卡应用于Internet应用措施之中。智能卡已经在日本和欧洲广为应用,而且在美国受到了接待。事实上,在美国的智能卡业界最近共产生了三件颇具意义的事件:
PC/SC
Microsoft连系其它几家公司推出了称为PC/SC的智能卡应用措施尺度,用于Win32平台的小我私家计较机与智能卡之间实现互通信。PC/SC今朝不支持非Win32的系统平台,或者Microsoft 永远也不会那样做。稍后我们将对此详加接头。
OpenCard框架
OpenCard是一个开放式的尺度,它支持智能卡应用措施在网络计较机、POS、桌面和膝上计较机等平台之上实现互操纵。OpenCard许诺提供100%纯Java的智能卡应用措施。凡是智能卡应用措施不能完全借助于纯Java,因为它们必须与外设互通信或是操作客户之上的措施库。(虽然,没有OpenCard,我们仍然可以或许利用100%的纯Java,可是,智能卡的开拓者必须从新定制一个接口。)OpenCard还提供了一个到PC/SC的接口,使得开拓者得以利用现有Win32 平台上的设备。
JavaCard
JavaCard最初由Schlumberger提出,今朝已被JavaSoft拟定为一项尺度。Schlumberger 今朝在市场上只提供Java智能卡,并且该公司是第一个得到JavaCard许可的厂商。作为一项极有潜力占踞统治职位的智能卡尺度,JavaCard包罗了尺度的类库和API,使得Java小应用可以或许直接运行在遵循ISO7816尺度的智能卡之上。JavaCard对差异的应用措施提供安详和与芯片无关的运行情况。
留意:
尽量本文会合于智能卡主题,但更为重要的是你决不该囿于这一种设备之上。从我个 人角度将,我更为偏幸Dallas Semiconductor出产的“Ibutton”设备。它象一个小型便携的 信用卡一样,可是更为易用。为什么呢?因为你不再需要拿出钱包从几张卡中选出要用的 那一张,Ibutton就在你的手中。对了,它是一枚指环。
尽量存在无打仗型的智能卡(关于这方面的信息见下文),我认为Ibutton这样象珠宝 饰品一样的产物必然会有利可图。关于Ibutton详情请见参考资料。顺便说一句,八月份在 纽约的Java Internet Business Expo(JIBE)展会上,Java Commerce Team展示了“JavaRing”。
#p#副标题#e#
为什么利用智能卡?
利用智能卡有何长处呢?好,下面答复这个问题:
1.智能卡比磁卡更为靠得住
2.智能卡可以或许存储数百倍于磁卡的数据
3.智能卡比磁卡更难于被粉碎
4.智能卡可以被处理惩罚或是接纳
5.智能卡在家产上可用的范畴辽阔,并可提供多种成果
6.智能卡与便携的电子设备兼容,好比说电话、PC或是小我私家数字助手(PDA)
7.智能卡在不绝的成长(究竟它内部包括了一块计较机芯片)
智能卡的种类
正如前面所述,本文将会合接头两种范例的智能卡:存储和处理惩罚器型。可是今朝共有五个范例的智能卡:
存储智能卡
处理惩罚器智能卡
电子钱包
安详卡
JavaCard
#p#分页标题#e#
智能卡是硬件的便携部门,它必需借助于其它设备才气获取对某种显示设备或是网络的会见。可以将卡插入读卡器,这凡是称为智能卡终端;也可通过射频无线电波来实现。
智能卡以下面两种方法与阅读器或是吸收器互通信:
打仗智能卡:当智能卡前端的芯片与阅读器相打仗时,两者之间才通报信息。
无打仗智能卡:这种信息通报通过天线来举办,省去了手工插入或拔出智能卡的行动。有了无打仗型卡,你仅须走近阅读器,然后的信息通报将自动举办。这种范例的智能卡可用于对速度要求较高或是插入拔出并不行行的应用情况。
一些厂商对这两种范例的智能卡均已开始了出产。
为智能卡应用措施建设开拓情况
为了开拓智能卡应用措施,你只需要这几件对象:一个智能卡阅读器、与阅读器通信的软件、与插入阅读器的卡通信的软件,虽然还要有智能卡及相关硬件设备。
智能卡阅读器
为了与智能卡彼此通报信息,或是要开拓一套在智能卡上运行的应用措施,你必需拥有一个阅读器。这个阅读器使应用措施可以或许从智能卡吸收或是发出呼吁。在市场上有很多种类的阅读器,个中最为风行的是serial、PCCard和keyboard模子。(Keyboard模子老是不绝涌现,我们期望大局限的PC厂商能在1998年六月之前直接提供这种产物。)
本文之中利用serial(串行)阅读器支持设备。一个串行阅读器与计较机的串口毗连。请留意这里提供的代码同样合用于PCCard型的阅读器;很多的膝上设备内置了PCCard的端口。
每一家厂商都提供了本身的协议用来向阅读器输出数据。一旦你可以和阅读器互换信 息,你就可以用一种协议与智能卡举办通信:即借助于APDU名目与智能卡互通。(关于APDU 名目稍后接头。)假如你想本身选购阅读器,请参阅参考资料中的“Gemplus smart card readers”。
与阅读器互换信息的软件
本文中所罗列的智能卡需要配备一些面向工具的类。它们是:
遵循7816协议通信的ISO呼吁类
与阅读器通信的类
将数据转换为厂商特命名目标类
用于测试应用措施的软件
智能卡及相关硬件设备
正如本文前面所述,为了建设一个雷同于下面例子的应用措施,你必需拥有智能卡的配套硬件和几块智能卡。你可以从Gemplus和Schlumberger等公司购置智能卡开拓东西。
假如你已经拥有了阅读器,要想利用它,还要配备下面将要谈到的接口类。前面已经讲过,在与智能卡通信之前,我们必需首先和阅读器打交道。并且就象现存的很多种类的智能卡一样,如今已经有了许很多多的阅读器。
重要的智能卡尺度
智能卡应用措施开拓中容易使人疑惑的一点是尺度协议问题。在我们的例子中根基上是应用措施与阅读器通信,然后由阅读器以一种尺度协议与智能卡通信。而这种尺度是国际尺度化组织的7816协议。
象其它很多新技能一样,关于智能卡有许很多多令人目眩凌乱的技能尺度。对付下面这些尺度形成劈头的相识之后,你就会概略上把握智能卡应用措施设计的根基技能要点。虽然对付一些系统的非凡尺度还须别的把握。我把这一向、整套尺度分成“横向的”和“纵向的”两个部门:横向的尺度可以被所有的应用措施所用,而纵向的尺度仅仅合用于特定的系统。
横向的尺度
ISO7816–描写到智能卡底层接口尺度。这种尺度界说智能卡阅读器和智能卡之间如何通报字节约。
PC/SC–界说运行Win3.1/Win95/NT的呆板与智能卡之间通信的尺度。
OCF–界说从Java应用情况和智能卡之间的通信尺度,该尺度完全是Java接口。(很快,OCF 将答允开拓者向OCF输出,并执行转换,这样开拓者再无须要利用PC/SC了。)
JavaCard–描写JavaCard和它所支持的尺度。
纵向的尺度
Mondex–以智能卡形式实现的数据现金。Mondex不答允存在于卡片之外的现金。
VisaCash–这种借贷卡可以用于跟踪处事器上的卡。
Proton–别的一种形式的电子钱币卡
MPCOS-EMV–这是一种通用的智能卡,它答允你实现本身的钱币或是令牌。
#p#分页标题#e#
我本身经常感受到迷惑不解:对付这样一块小小的塑料卡片,为什么会有如此之多的文档描写其尺度,并且开拓者又要把握大量的常识才气去开拓它?
因为举办智能卡的开拓要求高度的专业常识,所以市场上需要支持Beans的产物,这种产物应该用横向的尺度去实现纵向尺度的。这意味着你可以利用各式百般的横向尺度组合开拓出Beans产物来,就象OpenCard一样,为了实现特定的一个应用措施而回收其它几家商用尺度或是其它的应用措施。
Java小应用或是Java应用措施与智能卡之间的通信
你知道了如何将所有硬件毗连在一起。此刻我们需要如何利用一些API,这些API可以从应用措施向智能卡阅读器发出呼吁。(阅读器然后与智能卡打交道,作为一个应用措施到智能卡之间的信息通报前言。)智能卡阅读器移动其与智能卡打仗的金属尖端通报数据。智能卡对数据做出处理惩罚之后反还给阅读器,而阅读器再将之传会应用措施。下面的问题是,在这些数据从应用措施流向智能卡之时,它们毕竟处于那里?
正如前所述,应用措施与阅读器通信,而阅读器将利用上面先容的尺度再与智能卡通信。根基上,跟着智能卡技能的成长,ISO推出了一套智能卡尺度。该尺度界说了智能卡的机器和电器特性以及与智能卡通信的尺度。与ISO该尺度相关的文档列在参考资料傍边。不幸的是,ISO没有可以或许提供与阅读器彼此通信的尺度。因此,为了向智能卡发出一条呼吁,首先你要找出智能卡支持的呼吁荟萃,将该呼吁用ISO呼吁包封装,然后将这个包再以适合于阅读器的名目封装。下面的例程正是完成所有这些琐事。
Application Procotols Data Units(APDUs)
与智能卡互换信息的根基单位就是APDU包。从应用措施层传出的呼吁动静,加上从智能卡返回到应用措施的回应动静均称为ApplicationProcotolsDataUnits(APDU)。与智能卡和阅读器的通信以APDU形式实现。一个APDU包可以看作包括完整指令或是回应的数据包。为了提供这样的成果,在ISO7816类型家属里有一部门为APDU界说了一个精采的布局。
APDU包括如下域:
呼吁APDU名目
CLA | INS | P1 | P2 | Lc | Data | Le |
回应APDU名目
Data | SW1 | SW2 |
下面是一些支持APDU传输的类及其成果描写:
Command–封装呼吁APDU
Response–封装回应APDU
ISOCardReader–划定一个接口。每一种设备必需实现该接口
ISOCommand–组成一个ISOCommand并从ISOCardReader接口执行该呼吁与智能卡通信
Sun开拓了JavaElectronicCommerceFramework(JECF),这是对焦点Java平台的扩展,它答允开拓者轻松快速的开拓商用电子应用措施。JECF提供几种与智能卡通信的类。
我们这里接头的智能卡别离有一条读取数据和写入数据的呼吁。它是由GemPlus提供的名为GFM卡。你也可以利用其它范例的智能卡,只要它们支持ISO7816尺度而且你相识它们的APDU呼吁名目。虽然还要做一点措施事情。GFM卡的内存是以64个比特或是8个字节为单元的。你必需用模8的算法读写数据。换句话说,你不能向GFM卡做一次长度为1k持续的写入。我们这里提供的Java代码完成这项成果。一些新的智能卡支持更大单元的读写单元。因此,为了写入字符串“0123456789”,你必需发出两条适当编址的呼吁。(是的,智能卡就是这样难于编程。)当存储型卡和处理惩罚器型卡彼此融适时,这种限制也许会消失。
为了读取上面那条字符串,你应该发出“read”呼吁。这两种呼吁凭据APDU的术语被名目化的写在了下面。在我们的例子中操作了Java读写智能卡。下面表中的值示出如何构成一个APDU。在GCM编程指南中界说了APDU的布局。
Location of data Upper Lower
256 0x00 0x00
1023 0x00 0x00
3093 0x00 0x00
“upper”和“lower”是地点的高位和低位字节。举几个例子大概会有助于明了观念。这张 表的upper和lower值提供了存储数据简直定地点。我们接头过的向GPM896智能卡通信的两 种要领是:
ISOCommand(0,0xD0,0,upper,lower,8);//Write 8 bytes to the address
ISOCommand(0,0xB0,0,upper,lower,8);//Read 8 bytes from the address
欣赏器与智能卡之间的通信
#p#分页标题#e#
三个当地接口的存在表白对主要的开拓者团体缺乏相识,没有可以或许充实思量如何向处 于Java开拓情况的开拓者们提供简朴易于影象的API。假如所有的销售商均支持JNI,至少 接口可保持一致,你不必化大量的时间去把接口绑定。虽然你必需书写少量的当地代码,但 拥有统一的接口照旧有代价的。我实验了所有三种API,最终发明JNI要比其它的更为一致,而且也最为简朴、易于实现。连系HotJava一块利用是最佳的,这样你可以对与串口通信的 类签名,然后安详的利用它们,比起别的两种欣赏器来讲贫苦要少的多。Sun最近还公布帮 助欣赏器公司实现新版JDK/JVM的发起。
前面的接头环绕如何与一个不支持JDK的硬件设备通信。在下面的几篇文章里我们将不再利用“当地接口”,而是利用一个家产尺度与智能卡通信。我所选择的这项尺度就是带有PC/SC桥的OpenCard尺度。我将用OpenCard而不是PC/SC书写应用措施,为什么呢?
作为开拓者,你拥有多种选择。凡是来讲这是一件功德,但这也大概导致本钱升高和功 能的纷歧致性,尤其是当你选择的API并不被多种平台所支持时。譬喻,你抉择用PC/SC尺度 书写支持Win32系列平台的智能卡应用措施。假如你的应用措施是一个顾主利用的应用并 且将用在WebTV之上,你的选择就是完全错误的。显示器大将会闪动一条信息:“期待WebTV 的Pentium版本。”智能卡是用在Win32桌面和CE单位以外的市场之上的。那么你应该如何呢 ?利用OpenCard尺度,丢弃缺乏一致JNI绑定的Internet Explorer。事实上,我认为将所有API 抽象至单一平台是一个极为明智的选择。
实用的应用措施
此刻应该开始编写一个更具实用代价的智能卡应用措施了。未来,我们去看大夫,他发起采纳特定的治疗,我们大概处于如下局势:
大夫要求你的处方卡。
卡被插入阅读器,大夫查察你以前的处地契。(对付拥有巨大医疗汗青的人来说,大概需要一个专家系统。)
大夫留意到与此同时别的一位大夫在为你治疗,而他们俩人开出的药方有不良回响。因此今朝这位大夫就会向智能卡输入别的一种药方。(抱负化的功效是:智能卡可以将药方传给药房。)
你此刻可以将卡取出送到药房并插入哪里的阅读器。
配药师读出你的药房单。
设想配药师比大夫更为相识药性,他认为大夫应该从头思量所开出的药方。配药师给大夫打电话,而电话号码包罗在智能卡的记录之中。颠末短暂的接头之后,两小我私家告竣了一致而且更新卡中的记录。
配药师填写你的药地契,将院方的打算信息从卡中取出,并用加密的协议与之通信。
院方验证你是真正的成员,药方出自授权大夫之手,而且当令更新卡上的数据。
配药师向你收取5美元。
这听起来是不是一个更为安详的系统?虽然是较量今朝的系统而言,此刻根基上是纸和笔的时代,人充当相相互疏散的计较机系统的毗连点。事实上在德国,医疗智能卡已经在利用了。
智能处方卡的利益
较量传统的处方打算卡片而言,智能卡到底带给我们那些长处呢?下面将它们一一摆列出来:
当你要改变卡中的数据、出门观光或是到新的医疗机构之时,可以得到以前接管治疗时开具的各类处方数据。
在告抢救护或是ER事恋人员需要时实时的提供已往的医疗和照顾护士汗青。
详尽清晰的医疗汗青信息,包罗时间、所在和水平等详细信息。
可以有所选择的将数据提供应特定的人员,虽然也可选择从那里接管数据更新。
为了对以上的利益提供支持,我们需要开拓一个应用措施,答允我们用一种安详的方法向智能卡读写数据。假如拥有了硬件设备,我们需要将特定的字符串写入或从智能卡读出。这些要通过挪用CardStrings.java中提供的要领来完成。这些原形类的提供大大便利了对智能卡的编程事情。我们还添加了一个Beans气势气魄的事件处理惩罚器,用以通知用户象智能卡的插入这样的事件。(这最后一点的改造要感激JECF的高级高级开拓人员DanGuinab。)
思量如下来自RWString.java的代码片断:
import java.commerce.smartcards.*; Packages form JECF to support smart cards
import java.commerce.gemplus.*;
import java.commerce.DeviceManager.*;
import java.awt.event.*;
/**
* Read and write Gemplus Memory cards. The following cards
* are supported:
* GFM 4k
*/
public class RWString {
public static void main( String args[]) {
WriteString ws = new WriteString(args);
}
}
class WriteString implements ActionListener {
ISOCardReader isoReader = null;
int portNumber;
String deviceName;
public WriteString(String args[]) {
////////////////////////////////////
// Process the arguments
////////////////////////////////////
for(int i = 0; i
#p#分页标题#e#
CardStrings类提供了一些用于向智能卡读写字符串的要领。这些字符串在智能卡中的 存储开始于两个字节的长度域,后头随着六个空的字节,再后头是字符串数据。
对付那些真正开始智能卡应用措施开拓的人来说,必需面临一项挑战,那就是修改Cardstring 的要领,完成Java工具的读写。这种事情要比读写字符串来得更为机动。假如实现了Java工具的写入,你就不必思量所要存储数据的名目。我想从一个各人都说得出的简朴问题入手,即将字符串存储到智能卡中。
下面的例子是一个完整的数据读写应用措施,它合用于GCR400阅读器和GemPlusGFM 智能卡。仅需一点点的附加事情它就可以支持其它范例的阅读器。但你不必操心去做那样的事情,因为下个月里,我们将提供一个用OpenCard完成这种事情的例子。这种OpenCard将迅速成为这个行业中的尺度。
package java.commerce.MemoryCards;
import java.io.IOException;
import java.commerce.smartcards.*;
import java.commerce.gemplus.*;
public class CardStrings {
/**
* Write a String, since the card is modulo 8 and we are
* not using serialized objects -- the first two bytes are the
* length followed by six spare bytes. Strings longer than 4096 - 48
* bits will be truncated.
*/
public static void writeGFMString(String s ,
ISOCardReader isoreader) {
ISOCommand wcmd;
ISOCardinputStream winput;
int upper,lower;
short length = (short)s.length();
// Length of the input string
System.out.println("Length is " + length );
try {
// Write the control section out
wcmd = new ISOCommand(0, 0xd0, 0, 0, 8,0);
// Save the length
wcmd.data.writeShort( length );
System.out.println("Write out the Length");
winput = wcmd.execute(isoreader,
new GemplusReaderFailureHandler());
// Write the String out
int wholeAmount = length/8;
// Groups of 8
int remainder = length % 8;
// Remainder
// Write the String out groups of 8
for ( int l = 1; l <= wholeAmount; l++ ) { System.out.println("Writing 8 bytes at " + (l*8)); upper="(l" * 8 )>> 8;
lower = ( l * 8 ) & 0xff;
wcmd = new ISOCommand(0, 0xd0, upper, lower, 8,0);
int index = ( (l-1) * 8 );
wcmd.data.writeString(s.substring(index),8);
System.out.println("Write out bytes at " + index);
winput = wcmd.execute(isoreader,
new GemplusReaderFailureHandler());
}
// Write the remainder out
upper = ((wholeAmount+1) * 8 ) >> 8;
lower = ((wholeAmount+1) * 8 ) & 0xff;
wcmd = new ISOCommand(0, 0xd0, upper,
lower, remainder,0);
int index = ( wholeAmount * 8 );
wcmd.data.writeString(s.substring(index),remainder);
winput = wcmd.execute(isoreader,
new GemplusReaderFailureHandler());
} catch ( Exception e ) {
System.out.println( "Exception " + e);
e.printStackTrace();
}
}
/**
* Read a String, since the card is modulo 8 and we are
* not using serialized objects -- the first two bytes are the
* length followed by six spare bytes. Strings longer than 4096 - 48
* bits will be truncated.
*/
public static String readGFMString(ISOCardReader isoreader ) {
ISOCommand rcmd;
ISOCardinputStream rinput;
int upper,lower;
short length;
StringBuffer sb = new StringBuffer();
try {
// Read the control section
rcmd = new ISOCommand(0, 0xb0, 0, 0, 0, 8);
// Read the length
rinput = rcmd.execute(isoreader,new GemplusReaderFailureHandler());
length = (short)rinput.readShort();
System.out.println("The length is: " + length);
// Read the String
int wholeAmount = length/8; // Groups of 8
int remainder = length % 8; // Remainder
// Read the String in groups of 8
for ( int l = 1; l <= wholeAmount; l++ ) { System.out.println("Reading 8 bytes at " + (l*8)); upper="(l" * 8 )>> 8;
lower = ( l * 8 ) & 0xff;
rcmd = new ISOCommand(0, 0xb0, upper, lower, 0, 8);
rinput = rcmd.execute(isoreader,new GemplusReaderFailureHandler());
sb.append ( rinput.readString(8) );
System.out.println("String to this point:" + sb.toString());
}
// Read the remainder
upper = ( (wholeAmount+1) * 8 ) >> 8;
lower = ( (wholeAmount+1) * 8 ) & 0xff;
rcmd = new ISOCommand(0, 0xb0, upper, lower, 0, 8);
rinput = rcmd.execute(isoreader,new GemplusReaderFailureHandler());
sb.append ( rinput.readString(remainder) );
System.out.println("String to this point:" + sb.toString());
} catch ( Exception e ) {
System.out.println( "Exception " + e);
e.printStackTrace();
return ( null );
}
return ( sb.toString() );
}
}
结论
#p#分页标题#e#
本文为这一系列关于智能卡的文章做了一个铺垫事情。在JavaWorld中的这一系列专题 包罗四篇文章。均将由本文作者提供,但愿对付你在智能卡方面的应用措施开拓有所裨益。 我将操作Java Electronic Commerce Framework(JECF)作为构筑利用措施的基本布局。JECF 为简化与智能卡的通信提供了几个类。措施中的大部门代码和例子来自JECF。你可以从参 考资料中找到下载JECF的要领,那之中已经包罗了对智能卡的支持。