第 14 章


使用 SATSA

安全和信任服务 API (Security and Trust Services API, SATSA) 使小型设备上运行的应用程序具备智能卡访问和加密功能。JSR 177(SATSA 规范)定义了四种不同的 API,作为可选包:

Sun JavaTM Wireless Toolkit for CLDC 仿真器完全支持 SATSA。本章介绍如何使用 Sun JavaTM Wireless Toolkit for CLDC 在您自己的应用程序中使用 SATSA。

有关 SATSA 以及在小型设备中使用智能卡的一般介绍,请参见 SATSA Developer's Guide,可从以下位置获得:
http://java.sun.com/j2me/docs/satsa-dg/。

Sun JavaTM Wireless Toolkit for CLDC 中包含 Java Card 平台模拟器,用户可以使用它模拟 Sun JavaTM Wireless Toolkit for CLDC 仿真器插槽中的智能卡。可以在以下位置找到 Java Card 平台模拟器。


对于 Windows 系统:

toolkit\bin\cref.exe

对于 Linux 系统:

toolkit/bin/cref


 

以下简称为 cref。

如果用户需要开发自己的 Java Card 应用程序,请从 http://java.sun.com/products/javacard/ 网站上下载 Java Card 开发工具包。


14.1 仿真器中的卡插槽

真实 SATSA 设备可能具有一个或多个可插入智能卡的插槽。使用 SATSA 与智能卡进行通讯的应用程序需指定一个插槽和卡应用程序。

由于 Sun JavaTM Wireless Toolkit for CLDC 仿真器不是真实设备,因此不具有智能卡的物理插槽,而是使用套接字协议与智能卡应用程序进行通讯。套接字的另一端可以为智能卡仿真器或与真实智能卡硬件进行通讯的代理。

Sun JavaTM Wireless Toolkit for CLDC 仿真器包含两个模拟的智能卡插槽。每个插槽均具有关联的套接字,表示用于与智能卡应用程序进行通讯的协议的一端。用户可为每个插槽设置套接字端口号。选择“编辑”>“首选项”,然后单击 "SATSA" 选项卡。插槽 0 的默认端口为 9025,插槽 1 的默认端口为 9026。

图 14-1 为智能卡插槽设置端口号

显示 SATSA 类别的“首选项”窗口设置插槽 0 和插槽 1 的端口号、卡仿真器主机名和模拟器类型。


14.2 使用 Java Card 平台模拟器

通过 Sun JavaTM Wireless Toolkit for CLDC 测试 SATSA 应用程序的基本步骤如下:

1. 使用 Java Card 平台应用程序启动 cref。

2. 启动 Sun JavaTM Wireless Toolkit for CLDC 仿真器。

SATSA 应用程序在尝试与智能卡进行通讯时,会使用套接字连接与cref 进行通讯。

因此,请务必确保所启动 cref 时所使用的端口号与在 Sun JavaTM Wireless Toolkit for CLDC 的首选项中指定的其中一个插槽端口号相同。

例如,用户可使用以下命令行在具有预生成的内存映像的端口 9025 上运行 cref:

cref -p 9025 -i memory_image.eeprom

Sun JavaTM Wireless Toolkit for CLDC 包含演示应用程序 Mohair,其演示了如何使用 SATSA。有关运行 Mohair 的详细指导,请参见附录 A。


14.3 使用具有 SATSA 的网络监视器

Sun JavaTM Wireless Toolkit for CLDC 可显示在网络监视器中与模拟的智能卡应用程序交换的数据。网络监视器显示在仿真器和智能卡模拟器之间交换的应用协议数据单元 (Application Protocol Data Units, APDU)。其还可以显示使用 Java Card 远程方法调用(Java Card RMI)协议交换的数据。网络监视器中的 "APDU" 和 "JCRMI" 选项卡显示了通过智能卡交换的数据。

网络监视器可以解析每个 APDU,并根据需要显示请求和响应中的字段。

图 14-2 在网络监视器中查看 APDU

选择了 "APDU" 选项卡的网络监视器


14.4 调整访问控制

可在文本文件中指定访问控制权限和 PIN 属性。建立第一个 APDU 或 Java Card RMI 连接后,实现会读取位于 workdir\appdb 目录下 acl_slot-number 中的 ACL 和 PIN 数据。例如,插槽 0 的访问控制文件为 workdir\appdb\acl_0。如果文件不存在或包含错误,则将禁用该插槽的访问控制验证。

该文件可以包含有关 PIN 属性和应用程序权限的信息。

14.4.1 指定 PIN 属性

在访问控制文件中,PIN 属性通过 pin_data 记录表示。


pin_data {
    label string
    id number
    type       bcd | ascii | utf | half-nibble | iso
    min        minLength - 
    stored     storedLength
    max        maxLength
    reference  byte
    pad        byte - 可选
    flag       case-sensitive | change-disabled |
               unblock-disabled | needs-padding |
               disable-allowed | unblockingPIN
   }

 

14.4.2 指定应用程序权限

应用程序的权限在访问控制文件 (acf) 记录中进行定义。


acf AID f由空格分隔的数字 {
    ace {
         root CA 名称
         ...
         apdu {
                由空格分隔的八个数字
                ...
         }
         ...
         jcrmi {
                 classes {
                   类名
                   ...
                   }
                    hashModifier 字符串
                    methods {
                   方法名称和签名
                   ...
                 }
         }
         ...
         pin_apdu {
                 id number
            verify | change | disable | enable | unblock
            四个十六进制的数字
                 ...
         }
         ...
         pin_jcrmi {
                id number
            verify | change | disable | enable | unblock
            方法名称和签名
                ...
           }
        ...
        }
    ...
}

 

acf 记录是一个访问控制文件。acf 之后的 AID 用于标识应用程序。缺少 AID 表示该条目将应用于所有应用程序。acf 记录可包含 ace 记录。如果没有 ace 记录,则该 acf 将限制对应用程序的访问。

ace 记录是一个访问控制条目。它可以包含 root、apdu、jcrmi、pin_apdu 和 pin_jcrmi 记录。

root 记录包含一个 CA 名称。如果 MIDlet 套件是使用由该 CA 颁发的证书进行授权的,则该 ace 将授予访问该 MIDlet 的权限。缺少 root 字段则表示 ace 将应用于所有标识的部分。一行描述一个主体。此行必须只包含字 root 以及主体名称,例如:

root CN=thehost;OU=JCT;O=dummy CA;L=Santa Clara;ST=CA;C=US

apdu 或 jcrmi 记录介绍 APDU 或 Java Card RMI 权限。缺少权限记录则表示允许执行所有操作。

APDU 权限包含一组或多组八个十六进制值序列,由空格分隔。前四个字节描述 APDU 命令,其余四个字节为掩码,例如:

apdu {
    0 20  0 82  0 20  0 82
    80 20  0  0 ff ff  0  0
}

Java Card RMI 权限包含有关散列修饰符(可选)、类列表以及方法列表(可选)的信息。如果方法列表为空,则允许应用程序调用类列表中接口的所有远程方法,例如:


jcrmi {
    classes {
             com.sun.javacard.samples.RMIDemo.Purse
    }
    hashModifier zzz
    methods {
        debit(S)V
        setAccountNumber([B)V
        getAccountNumber()[B
    }
}

 

所有的数字均为十六进制。制表符、空格符、回车符及换行符用作分隔符。符号 { 和 } 前后可省略分隔符。

pin_apdu 和 pin_jcrmi 记录包含 PIN 条目方法所必需的信息,这些信息为 PIN 标识符和 APDU 命令标题,或远程方法名称。

14.4.3 访问控制文件示例


pin_data {
  label   Unblock pin
  id        44
  type      utf
  min       4
  stored    8
  max       8
  reference 33
  pad       ff
  flag      needs-padding
  yflag     unblockingPIN
}
pin_data {
  label     Main pin
  id        55
  type      half-nibble
  min       4
  stored    8
  max       8
  reference 12
  pad       ff
  flag      disable-allowed
  flag      needs-padding
}
 
acf a0 0 0 0 62 ff 1 {
  ace {
        root CN=thehost;OU=JCT;O=dummy CA;L=Santa Clara;ST=CA;C=US
  
        pin_jcrmi {
            id 55
            verify enterPIN([B)S
            change changePIN([B[B)S
            disable disablePIN([B)S
            enable enablePIN([B)S
            unblock unblockPIN([B[B)S
           }
  }
}
 
acf a0 0 0 0 62 ee 1 {
  ace {
    root CN=thehost;OU=JCT;O=dummy CA;L=Santa Clara;ST=CA;C=US
 
    pin_apdu {
            id 55
            verify 1 2 3 1
            change 4 3 2 2
            disable 1 1 1 3 
            enable 5 5 5 4
            unblock 7 7 7 5
        }
  }
}
 
acf a0 0 0 0 62 3 1 c 8 1 {
  ace {
        root CN=thehost;OU=JCT;O=dummy CA;L=Santa Clara;ST=CA;C=US
 
        jcrmi {
                 classes {
                     com.sun.javacard.samples.RMIDemo.Purse
              }
                 hashModifier xxx
                 methods {
                   setAccountNumber([B)V
                   getBalance()S
                   credit(S)V
                 }
  }
}
  ace {
        jcrmi {
                classes {
                     com.sun.javacard.samples.RMIDemo.Purse
                  }
 
                  debit(S)V
                  getAccountNumber()[B
              }
            }
       }
  }
  
acf a0 00 00 00 62 03 01 0c 02 01 {
  ace {
        root CN=thehost;OU=JCT;O=dummy CA;L=Santa Clara;ST=CA;C=US
        apdu {
               0 20  0 82  0 20  0 82
               80 20  0  0 ff ff  0  0
             }
        apdu {
               80 22  0  0 ff ff  0  0 
             }
        }
  }
acf a0 00 00 00 62 03 01 0c 02 01 {
 
  ace {
    apdu {
        0 20 0 82 ff ff ff ff
    }
  }
}
 
acf a0 00 00 00 62 03 01 0c 06 01 {
 
  ace {
    apdu {
        0 20 0 82 ff ff ff ff
    }
  }
}