Java 智 能 卡 基 础 篇

类别:Java 点击:0 评论:0 推荐:

从 本 文 开 始, 我 们 陆 续 刊 登 一 系 列 在 智 能 卡上 进 行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 对 不 同 的 应 用 程 序 提 供 安 全 和 与 芯 片 无 关

的 运 行 环境。

注 意:

尽 管 本 文 集 中 于 智 能 卡 主 题, 但 更 为 重 要 的是 你 决 不应 囿 于 这 一 种

设 备 之 上。 从 我 个 人 角 度 将, 我 更 为偏 爱DallasSemiconductor 生 产

的揑button?设 备。 它 象 一 个 小 型 便携 的 信 用卡 一 样, 但 是 更 为 易 用。

为 什 么 呢 ? 因 为 你 不 再 需要 拿 出 钱包 从 几 张 卡 中 选 出 要 用 的 那

一 张,Ibutton 就 在 你 的 手中。 对 了, 它 是 一 枚 指 环。尽 管 存 在 无 接 触

型 的 智 能 卡( 关 于 这 方 面 的信 息 见 下文), 我 认 为Ibutton 这 样 象 珠

宝 饰 品 一 样 的 产 品 一 定会 有 利 可图。 关 于Ibutton 详 情 请 见 参 考 资 料。

顺 便 说 一 句, 八月 份 在 纽约 的Java Internet Business Expo(JIBE) 展 会 上,

Java CommerceTeam 展 示 了揓avaRing敗?/P>

为 什 么 使 用 智 能 卡 ?

使 用 智 能 卡 有 何 好 处 呢 ? 好, 下 面 回 答 这 个

问 题:

1. 智 能 卡 比 磁 卡 更 为 可 靠

2. 智 能 卡 能 够 存 储 数 百 倍 于 磁 卡 的 数 据

3. 智 能 卡 比 磁 卡 更 难 于 被 破 坏

4. 智 能 卡 可 以 被 处 理 或 是 回 收

5. 智 能 卡 在 工 业 上 可 用 的 范 围 广 阔, 并 可 提供 多 种 功

6. 智 能 卡 与 便 携 的 电 子 设 备 兼 容, 比 如 说 电话、PC 或 是

个 人 数 字 助 手(PDA)

7. 智 能 卡 在 不 断 的 发 展( 毕 竟 它 内 部 包 含 了一 块 计 算

机 芯 片)

智 能 卡 的 种 类

正 如 前 面 所 述, 本 文 将 集 中 讨 论 两 种 类 型 的智 能 卡:

存 储 和 处 理 器 型。 但 是 目 前 共 有 五 个 类 型 的 智 能

卡:

存 储 智 能 卡

处 理 器 智 能 卡

电 子 钱 包

安 全 卡

JavaCard

智 能 卡 是 硬 件 的 便 携 部 分, 它 必 须 借 助 于 其它 设 备 才

能 获 取 对 某 种 显 示 设 备 或 是 网 络 的 访 问。 可 以 将 卡

插 入 读 卡器, 这 通 常 称 为 智 能 卡 终 端; 也 可 通 过 射 频 无 线 电

波 来 实 现。

智 能 卡 以 下 面 两 种 方 式 与 阅 读 器 或 是 接 收 器互 通 信:

接 触 智 能 卡: 当 智 能 卡 前 端 的 芯 片 与 阅 读 器相 接 触 时

, 两 者 之 间 才 传 递 信 息。

无 接 触 智 能 卡: 这 种 信 息 传 递 通 过 天 线 来 进行, 省 去

了 手 工 插 入 或 拔 出 智 能 卡 的 动 作。 有 了 无 接 触 型

卡, 你 仅 须走 近 阅 读 器, 然 后 的 信 息 传 递 将 自 动 进 行。 这 种 类

型 的 智 能卡 可 用 于 对 速 度 要 求 较 高 或 是 插 入 拔 出 并 不 可 行 的

应 用 环 境。

一 些 厂 商 对 这 两 种 类 型 的 智 能 卡 均 已 开 始 了生 产。

为 智 能 卡 应 用 程 序 创 建 开 发 环 境

为 了 开 发 智 能 卡 应 用 程 序, 你 只 需 要 这 几 件东 西: 一

个 智 能 卡 阅 读 器、 与 阅 读 器 通 信 的 软 件 、 与 插 入 阅

读 器 的 卡通 信 的 软 件, 当 然 还 要 有 智 能 卡 及 相 关 硬 件 设 备。

智 能 卡 阅 读 器为 了 与 智 能 卡 相 互 传 递 信 息, 或 是 要 开 发 一

套 在 智 能卡 上 运 行 的 应 用 程 序, 你 必 须 拥 有 一 个 阅 读 器。 这

个 阅 读 器使 应 用 程 序 能 够 从 智 能 卡 接 收 或 是 发 出 命 令。 在 市

场 上 有 许多 种 类 的 阅 读 器, 其 中 最 为 流 行 的 是serial、 PCCard 和

keyboard 模型。(Keyboard 模 型 总 是 不 断 涌 现, 我 们 期 望 大 规 模 的

PC 厂 商 能在1998 年 六 月 之 前 直 接 提 供 这 种 产 品。)

本 文 之 中 使 用serial( 串 行) 阅 读 器 支 持 设 备。

一 个 串 行阅 读 器 与 计 算 机 的 串 口 连 接。 请 注 意 这 里 提 供 的 代

码 同 样 适用 于PCCard 型 的 阅 读 器; 许 多 的 膝 上 设 备 内 置 了PCCard

的 端 口。每 一 家 厂 商 都 提 供 了 自 己 的 协 议 用 来 向 阅 读

器 输 出 数据。 一 旦 你 可 以 和 阅 读 器 交 换 信 息, 你 就 可 以 用 一

种 协 议 与智 能 卡 进 行 通 信: 即 借 助 于APDU 格 式 与 智 能 卡 互 通。

( 关 于APDU 格 式 稍 后 讨 论。) 如 果 你 想 自 己 选 购 阅 读 器, 请 参

阅 参 考 资料 中 的揋emplus smart card readers敗?/P>

与 阅 读 器 交 换 信 息 的 软 件

本 文 中 所 列 举 的 智 能 卡 需 要 配 备 一 些 面 向 对

象 的 类。

它 们 是:

遵 循7816 协 议 通 信 的ISO 命 令 类

与 阅 读 器 通 信 的 类

将 数 据 转 换 为 厂 商 特 定 格 式 的 类

用 于 测 试 应 用 程 序 的 软 件

智 能 卡 及 相 关 硬 件 设 备

正 如 本 文 前 面 所 述, 为 了 创 建 一 个 类 似 于 下面 例 子 的

应 用 程 序, 你 必 须 拥 有 智 能 卡 的 配 套 硬 件 和 几 块 智

能 卡。 你可 以 从Gemplus 和Schlumberger 等 公 司 购 买 智 能 卡 开 发 工

具。

如 果 你 已 经 拥 有 了 阅 读 器, 要 想 使 用 它, 还要 配 备 下

面 将 要 谈 到 的 接 口 类。 前 面 已 经 讲 过, 在 与 智 能 卡

通 信 之 前,我 们 必 须 首 先 和 阅 读 器 打 交 道。 而 且 就 象 现 存 的 许

多 种 类 的智 能 卡 一 样, 如 今 已 经 有 了 许 许 多 多 的 阅 读 器。

重 要 的 智 能 卡 标 准

智 能 卡 应 用 程 序 开 发 中 容 易 使 人 迷 惑 的 一 点是 标 准 协

议 问 题。 在 我 们 的 例 子 中 基 本 上 是 应 用 程 序 与 阅 读

器 通 信,然 后 由 阅 读 器 以 一 种 标 准 协 议 与 智 能 卡 通 信。 而 这

种 标 准 是国 际 标 准 化 组 织 的7816 协 议。

象 其 它 许 多 新 技 术 一 样, 关 于 智 能 卡 有 许 许多 多 令 人

眼 花 缭 乱 的 技 术 标 准。 对 于 下 面 这 些 标 准 形 成 初 步

的 了 解 之后, 你 就 会 大 体 上 掌 握 智 能 卡 应 用 程 序 设 计 的 基 本

技 术 要 点。 当 然 对 于 一 些 系 统 的 特 殊 标 准 还 须 另 外 掌 握。 我

把 这 一 向、 整 套 标 准 分 成?横 向 的?和?纵 向 的?两 个 部 分:

横 向 的 标准 可 以 被 所 有 的 应 用 程 序 所 用, 而 纵 向 的 标 准 仅 仅

适 用 于 特定 的 系 统。

横 向 的 标 准

ISO 7816-- 描 述 到 智 能 卡 底 层 接 口 标 准。 这 种 标 准 定义 智 能 卡

阅 读 器 和 智 能 卡 之 间 如 何 传 递 字 节 流。

PC/SC-- 定 义 运 行Win3.1/Win95/NT 的 机 器 与 智 能 卡 之 间 通

信 的 标 准。

OCF-- 定 义 从Java 应 用 环 境 和 智 能 卡 之 间 的 通 信 标 准,该 标 准 完

全 是Java 接 口。( 很 快,OCF 将 允 许 开 发 者 向OCF 输 出,并 执 行 转

换, 这 样 开 发 者 再 无 必 要 使 用PC/SC 了。)

JavaCard-- 描 述JavaCard 和 它 所 支 持 的 标 准。纵 向 的 标 准

Mondex-- 以 智 能 卡 形 式 实 现 的 数 据 现 金。Mondex 不 允 许存 在 于 卡

片 之 外 的 现 金。

VisaCash-- 这 种 借 贷 卡 可 以 用 于 跟 踪 服 务 器 上 的 卡。

Proton-- 另 外 一 种 形 式 的 电 子 货 币 卡

MPCOS-EMV-- 这 是 一 种 通 用 的 智 能 卡, 它 允 许 你 实 现 自己 的 货 币

或 是 令 牌。

我 自 己 常 常 感 觉 到 疑 惑 不 解: 对 于 这 样 一 块小 小 的 塑

料 卡 片, 为 什 么 会 有 如 此 之 多 的 文 档 描 述 其 标 准,而 且 开 发

者 又 要 掌 握 大 量 的 知 识 才 能 去 开 发 它 ?

因 为 进 行 智 能 卡 的 开 发 要 求 高 度 的 专 业 知识, 所 以 市

场 上 需 要 支 持Beans 的 产 品, 这 种 产 品 应 该 用 横 向 的

标 准 去 实现 纵 向 标 准 的。 这 意 味 着 你 可 以 使 用 各 式 各 样 的 横

向 标 准 组合 开 发 出Beans 产 品 来, 就 象OpenCard 一 样, 为 了 实 现 特

定 的 一 个应 用 程 序 而 采 用 其 它 几 家 商 用 标 准 或 是 其 它 的 应

用 程 序。

Java 小 应 用 或 是Java 应 用 程 序 与 智 能 卡 之 间 的 通 信

你 知 道 了 如 何 将 所 有 硬 件 连 接 在 一 起。 现 在我 们 需 要

如 何 使 用 一 些API, 这 些API 可 以 从 应 用 程 序 向 智 能 卡

阅 读 器 发出 命 令。( 阅 读 器 然 后 与 智 能 卡 打 交 道, 作 为 一 个

应 用 程 序到 智 能 卡 之 间 的 信 息 传 递 媒 介。) 智 能 卡 阅 读 器 移

动 其 与 智能 卡 接 触 的 金 属 尖 端 传 递 数 据。 智 能 卡 对 数 据 做 出

处 理 之 后反 还 给 阅 读 器, 而 阅 读 器 再 将 之 传 会 应 用 程 序。 下

面 的 问 题是, 在 这 些 数 据 从 应 用 程 序 流 向 智 能 卡 之 时, 它 们

究 竟 处 于何 处 ?正 如 前 所 述, 应 用 程 序 与 阅 读 器 通 信, 而 阅

读 器 将 使用 上 面 介 绍 的 标 准 再 与 智 能 卡 通 信。 基 本 上, 随 着

智 能 卡 技术 的 发 展,ISO 推 出 了 一 套 智 能 卡 标 准。 该 标 准 定 义

了 智 能 卡的 机 械 和 电 器 特 性 以 及 与 智 能 卡 通 信 的 标 准。 与ISO

该 标 准 相关 的 文 档 列 在 参 考 资 料 当 中。 不 幸 的 是,ISO 没 有 能

够 提 供 与阅 读 器 相 互 通 信 的 标 准。 因 此, 为 了 向 智 能 卡 发 出

一 条 命 令, 首 先 你 要 找 出 智 能 卡 支 持 的 命 令 集 合, 将 该 命 令

用ISO 命 令包 封 装, 然 后 将 这 个 包 再 以 适 合 于 阅 读 器 的 格 式 封

装。 下 面的 例 程 正 是 完 成 所 有 这 些 琐 事。

Application Procotols Data Units(APDUs)

与 智 能 卡 交 换 信 息 的 基 本 单 元 就 是APDU 包。 从应 用 程 序

层 传 出 的 命 令 消 息, 加 上 从 智 能 卡 返 回 到 应 用 程 序

的 回 应 消息 均 称 为Application Procotols Data Units(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 开 发 了Java Electronic Commerce Framework(JECF),

这 是 对 核心Java 平 台 的 扩 展, 它 允 许 开 发 者 轻 松 快 速 的 开 发 商

用 电 子 应用 程 序。JECF 提 供 几 种 与 智 能 卡 通 信 的 类。

我 们 这 里 讨 论 的 智 能 卡 分 别 有 一 条 读 取 数 据和 写 入 数

据 的 命 令。 它 是 由GemPlus 提 供 的 名 为GFM 卡。 你 也 可 以使 用 其 它

类 型 的 智 能 卡, 只 要 它 们 支 持ISO7816 标 准 并 且 你 了解 它 们 的A

PDU 命 令 格 式。 当 然 还 要 做 一 点 程 序 工 作。GFM 卡 的 内存 是 以64

个 比 特 或 是8 个 字 节 为 单 位 的。 你 必 须 用 模8 的 算 法读 写 数 据。

换 句 话 说, 你 不 能 向GFM 卡 做 一 次 长 度 为1k 连 续 的 写入。 我 们

这 里 提 供 的Java 代 码 完 成 这 项 功 能。 一 些 新 的 智 能 卡支 持 更 大

单 位 的 读 写 单 位。 因 此, 为 了 写 入 字 符 串?123456789敚?你 必 须

发 出 两 条 适 当 编 址 的 命 令。( 是 的, 智 能 卡 就 是 这样 难 于 编

程。) 当 存 储 型 卡 和 处 理 器 型 卡 相 互 融 合 时, 这 种 限制 也 许 会

消 失。

为 了 读 取 上 面 那 条 字 符 串, 你 应 该 发 出搑ead?命 令。 这

两 种 命 令 按 照APDU 的 术 语 被 格 式 化 的 写 在 了 下 面。在 我 们 的

例 子 中 利 用 了Java 读 写 智 能 卡。 下 面 表 中 的 值 示 出 如何 组 成 一

个APDU。 在GCM 编 程 指 南 中 定 义 了APDU 的 结 构。

Location of data Upper Lower

256 0x00 0x00

1023 0x00 0x00

3093 0x00 0x00

搖pper?和搇ower?是 地 址 的 高 位 和 低 位 字 节。

举 几 个 例子 可 能 会 有 助 于 明 晰 概 念。 这 张 表 的upper 和lower 值

提 供 了 存储 数 据 的 确 定 地 址。 我 们 讨 论 过 的 向GPM896 智 能 卡 通

信 的 两 种方 法 是:

ISOCommand(0,0xD0,0,upper,lower,8);//Write 8 bytes tothe address

ISOCommand(0,0xB0,0,upper,lower,8);//Read 8 bytes from

the address

浏 览 器 与 智 能 卡 之 间 的 通 信

三 个 本 地 接 口 的 存 在 表 明 对 主 要 的 开 发 者 集团 缺 乏 了

解, 没 有 能 够 充 分 考 虑 如 何 向 处 于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 的

高 级 高 级开 发 人 员Dan Guinab。)

考 虑 如 下 来 自RWString.java 的 代 码 片 段:

import java.commerce.smartcards.*; Packages form JECF to supportsmart 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 < args.length; i++) {

if ( args[i].equals("-port") ){

portNumber = 0;

} else if ( args[i].equals("-device") ) {

deviceName = new String ( args[++i] );

} else if ( args[i].equals("-help") ) {

System.out.println("Usage: string

-port # -device COM1 or /dev/ttya" );

System.exit(0);

}

}

SmartCardDetector scDetector = new

SmartCardDetector(1000);

scDetector.addActionListener(this);

scDetector.startDetection();

}

public void actionPerformed(ActionEvent actionEvent) {

System.out.println("Action Performed: " + actionEvent );

try {

// Open the requested port number

SmartCardReader scr = new SmartCardReader();

isoReader = scr.getDefault();

isoReader.beginCardSession(GemplusSerialReader.GFM);

CardStrings.writeGFMString("01234567" , isoReader );

System.out.println(CardStrings.readGFMString(isoReader ) );

isoReader.endCardSession();

} catch(Exception e) {

System.out.println( "Exception " + e);

e.printStackTrace();

} finally {

try {

isoReader.endCardSession();

} catch(Exception eFinally) {

System.out.println("Could not power

Down card perform manual reset");

}

}

}

}

CardStrings 类 提 供 了 一 些 用 于 向 智 能 卡 读 写 字符 串 的 方

法。 这 些 字 符 串 在 智 能 卡 中 的 存 储 开 始 于 两 个 字 节

的 长 度 域, 后 面 跟 着 六 个 空 的 字 节, 再 后 面 是 字 符 串 数 据。

对 于 那 些 真 正 开 始 智 能 卡 应 用 程 序 开 发 的 人来 说, 必

须 面 对 一 项 挑 战, 那 就 是 修 改Cardstring 的 方 法, 完 成

Java 对 象的 读 写。 这 种 工 作 要 比 读 写 字 符 串 来 得 更 为 灵 活。

如 果 实 现了Java 对 象 的 写 入, 你 就 不 必 考 虑 所 要 存 储 数 据 的 格

式。 我 想从 一 个 大 家 都 说 得 出 的 简 单 问 题 入 手, 即 将 字 符 串

存 储 到 智能 卡 中。

下 面 的 例 子 是 一 个 完 整 的 数 据 读 写 应 用 程

序, 它 适 用于GCR400 阅 读 器 和GemPlus GFM 智 能 卡。 仅 需 一 点 点 的 附

加 工 作 它就 可 以 支 持 其 它 类 型 的 阅 读 器。 但 你 不 必 费 心 去 做

那 样 的 工作, 因 为 下 个 月 里, 我 们 将 提 供 一 个 用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

GemplusReaderFailureHand

ler());

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() );

}

}

以 后 的 文 章

在 后 面 的 文 章 里 面, 我 们 将 讨 论 这 样 一 个 问题: 医 生

如 何 能 够 对 他 加 入 你 智 能 卡 中 的 条 目 进 行 安 全 的 签

名, 这 样处 方 卡 才 能 够 发 挥 它 的 实 际 作 用。 该 应 用 程 序 还 必

须 提 供 显示 你 处 方 卡 历 史 信 息 的 功 能。 这 样 的 功 能 可 以 为 用

户 自 己 所用, 当 然 也 可 提 供 给 药 剂 师 或 是 紧 急 救 护 人 员。 再

加 上 你 过去 医 疗 历 史 带 有 警 报 色 彩 的 概 要, 以 及 外 科 手 术 和

慢 性 病 等信 息, 你 的 智 能 处 方 卡 将 会 提 供 许 多 种 应 用 前 景。

结 论

本 文 为 这 一 系 列 关 于 智 能 卡 的 文 章 做 了 一 个铺 垫 工 作

。 在JavaWorld 中 的 这 一 系 列 专 题 包 括 四 篇 文 章。 均 将由 本 文 作

者 提 供, 希 望 对 于 你 在 智 能 卡 方 面 的 应 用 程 序 开 发有 所 裨 益

。 我 将 利 用Java Electronic Commerce Framework(JECF) 作 为 构筑 使 用 程

序 的 基 础 结 构。JECF 为 简 化 与 智 能 卡 的 通 信 提 供 了 几个 类。 程

序 中 的 大 部 分 代 码 和 例 子 来 自JECF。 你 可 以 从 参 考资 料 中 找

到 下 载JECF 的 方 法, 那 之 中 已 经 包 括 了 对 智 能 卡 的 支持。

本文地址:http://com.8s8s.com/it/it18899.htm