Page 227 - 捷運技術 第38期
P. 227

捷運技術半年刊 第38期 97年2月                                         221





            惡意攔截(Malicious Interception)之可能性已低,因此係以資料完整送達為首要目標,在
            MACing Key 上並無多樣化之需要,且其管理權歸屬本局系統。
                 綜合上述,以下配合票證公司之金鑰管理系統做一整體描述,如附圖六,KMS負責產

            生主金鑰(Master Key),當負責管理金鑰之多人到齊後,分別輸入密碼並插入IC卡後系統
            產生Master Key A、Master Key B、Master MACing Key及 Diversify Key 。經接觸式IC卡,
            Master Key A、Master Key B及 Diversify Key 送至CIM(悠遊卡發卡機),多樣化演算後寫
            入每張首次發行之悠遊卡上。Master Key A、Master Key B、Master MACing Key及 Diversify
            Key寫入手提式電腦後,當各業者系統安裝完成後,由票證公司人員攜至設備安裝現場,輸

            入讀卡機唯一序號為參數予以金鑰多樣化演算後,再寫入讀卡機,作為與悠遊卡進行交易之
            確認金鑰及交易資料傳送所需MAC演算所需金鑰,而此動作即所謂系統安裝完成啟用前之
            Load Key動作,亦相當於票證公司之授權認可使用該讀卡機進行悠遊卡交易。另外為使清算

            中心電腦可確認送達之交易資料是否被竄改及傳送者身分,Master MACing Key以接觸式IC
            卡傳送至CCHS負責接收之電腦,作為演算參數。
                 這金鑰管理系統隱含一旦票卡之金鑰需置換則所有悠遊卡需回收再由CIM重新寫入新
            的金鑰,也代表讀卡機之置換需以手提電腦逐站逐設備重新Load Key。至於單程票部分就
            單純多了,各設備所需MAC金鑰及驗證單程票所需之Token金鑰,並無多樣化需要,且可由

            CDPS一路往下送至各相關設備。
            (四)加密與摘要演算應用程式介面(API)
                 為進一步說明前述加密動作與MAC之實際運作,以下以8個步驟,配合Java API【5】概

            略說明程式實作加密、解密與摘要演算之方法,其他C++ 、C# 、VB 等程式語言亦有各自之
            API,可請參考相關網站。
            1. 首先產生金鑰(此處「交易資料塊」係指若干筆交易資料組合成之資料區塊;產生金鑰的
              動作是在票證公司之KMS上產生,多樣化後Load到悠遊卡讀寫模組儲存備用)

                     javax.crypto.KeyGenerator keyProducer = KeyGenerator.getInstance (“DES”);
                  //金鑰產生器
                 SecretKey MacKey = keyProducer.generateKey();   //金鑰產生器 在此產生金鑰
            2.  悠遊卡讀寫模組產生「欲傳送之交易資料塊」之訊息摘要(MessageDigest),這裡以採用

               SHA-1摘要演算
                 java.security.MessageDigest DigeAlgo=java.security.MessageDigest.getInstance("SHA-1");
                 加入要進行計算摘要的交易資料塊
                 DigeAlgo .update(欲傳送之交易資料塊.getBytes());

                 計算出摘要ResulltingDigest
                 byte[] ResulltingDigest= DigeAlgo .digest();
            3. 悠遊卡讀寫模組將「摘要」以對稱式加密演算法加密
                 javax.crypto.Cipher ctx = Cipher.getInstance(“DES”);

                 ctx.init(Cipher.ENCRYPT_MODE,  MacKey );         //以MacKey加密
                 byte[] MacTx=c1.doFinal(ResulltingDigest .getBytes());
   222   223   224   225   226   227   228   229   230   231   232