第 14 章


使用 SATSA

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 開發人員指南」,該指南可在
http://java.sun.com/j2me/docs/satsa-dg/ 上取得。

Sun JavaTM Wireless Toolkit for CLDC 包含 Java Card Platform Simulator,您可將其用於模擬 Sun JavaTM Wireless Toolkit for CLDC 模擬器槽中的智慧卡。Java Card 平台模擬器位於:


Windows:

toolkit\bin\cref.exe

Linux:

toolkit/bin/cref

下文中,我們將其簡稱為 cref。

如果需要開發自己的 Java Card 應用程式,請下載 Java Card Development Kit,其可以在 http://java.sun.com/products/javacard/ 上取得。


14.1 模擬器中的卡片槽

實際 SATSA 裝置可能具有用於插接智慧卡的一個或多個插槽。使用 SATSA 與智慧卡通訊的應用程式需要指定卡片槽和智慧卡應用程式。

Sun JavaTM Wireless Toolkit for CLDC 模擬器不是實際裝置,因此沒有智慧卡的實體插槽, 而是使用通訊端協定與智慧卡應用程式通訊。通訊端的另一端可能是智慧卡模擬器,或者可能是與實際智慧卡硬體通訊的代理協定。

Sun JavaTM Wireless Toolkit for CLDC 模擬器包含兩個模擬的智慧卡槽。每個槽都有一個相關聯的通訊端,代表和智慧卡應用程式通訊的協定之一端。您可以為每個槽設定通訊端連接埠號。請選擇 [編輯] > [偏好],然後按一下 [SATSA] 標籤。預設連接埠為 9025 用於槽 0 以及 9026 用於槽 1。

圖 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 Unit (APDU), 也可以顯示使用 Java Card Remote Method Invocation (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 - optional
    flag       case-sensitive | change-disabled |
               unblock-disabled | needs-padding |
               disable-allowed | unblockingPIN
   }

 

14.4.2 指定應用程式權限

應用程式權限要在存取控制檔 (acf) 記錄中定義。


acf AID f由空格分隔的數字 {
    ace {
         root CA name
         ...
         apdu {
                八個由空格分隔的數字
                ...
         }
         ...
         jcrmi {
                 classes {
                   classname
                   ...
                   }
                    hashModifier string
                    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 名稱。若使用此 CA 發出的憑證來授權 MIDlet 套件,則此 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
    }
}

所有數字均為十六進制。表格、空格、CR 和 LF 符號用作分隔符號。在符號 { 和 } 前後可以沒有分隔符號。

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
    }
  }
}