鴻蒙OS 訪問SE安全單元

2020-09-18 14:58 更新

場景介紹

應用或者其他模塊可以通過接口完成以下功能:

  1. 獲取安全單元的個數(shù)和名稱。
  2. 判斷安全單元是否在位。
  3. 在指定安全單元上打開基礎通道。
  4. 在指定安全單元上打開邏輯通道。
  5. 發(fā)送 APDU(Application Protocol Data Unit)數(shù)據(jù)到安全單元上。

接口說明

類名 接口名 功能描述
SEService SEService() 創(chuàng)建一個安全單元服務的實例。
isConnected() 查詢安全單元服務是否已連接。
shutdown() 關閉安全單元服務。
getReaders() 獲取全部安全單元。
getVersion() 獲得安全單元服務的版本。
OnCallback 用于回調的內部類,用于定義回調接口。在服務連接成功后,回調該接口通知應用。
Reader getName() 獲取安全單元的名稱。
isSecureElementPresent() 檢查安全單元是否在位。
openSession() 打開當前安全單元上的 session。
closeSession() 關閉當前安全單元上的所有 session。
Session openBasicChannel(Aid aid) 打開基礎通道。
openLogicalChannel(Aid aid) 創(chuàng)建邏輯通道。
getATR() 獲得重設安全單元指令的響應。
closeSessionChannels() 關閉當前 session的所有通道。
Channel isClosed() 判斷通道是否關閉。
isBasicChannel() 判斷是否是基礎通道。
transmit(byte[] command) 發(fā)送指令到安全單元。
getSelectResponse() 獲得應用程序選擇指令的響應。
closeChannel() 關閉通道。
Aid Aid(byte[] aid, int offset, int length) 構造一個 AID 類的實例。
isAidValid() 查詢AID是否有效。
getAidBytes() 獲取AID的字節(jié)數(shù)組形式的值。

開發(fā)步驟

  1. 調用 SEService 類的構造函數(shù),創(chuàng)建一個安全單元服務的實例,用于訪問安全單元。

  1. 調用 isConnected() 接口,查詢安全單元服務的連接狀態(tài)。

  1. 調用 getReaders() 接口,獲取本機的全部安全單元。

  1. 調用 Reader 類的 openSession() 接口打開 Session,返回一個打開的 Session 實例。

  1. 調用 Session 類的 openBasicChannel(Aid aid) 接口打開基礎通道,或者調用 openLogicalChannel(Aid aid) 接口打開邏輯通道,返回一個打開通道 Channel 實例。

  1. 調用 Channel 類的 transmit(byte[] command),發(fā)送 APDU 到安全單元。

  1. 調用 Channel 類的 closeChannel() 接口關閉通道。

  1. 調用 Session 類的 closeSessionChannels() 接口關閉 Session 的所有通道。

  1. 調用 Reader 類的 closeSessions() 接口關閉安全單元的所有 Session。

  1. 調用 SEService 類的 shutdown() 接口關閉安全單元服務。

    private class AppServiceConnectedCallback implements SEService.OnCallback {
        @Override
        public void serviceConnected() {
            // 應用自實現(xiàn)
        }
    }
    // 創(chuàng)建安全單元服務實例
    SEService sEService = new SEService(context, new AppServiceConnectedCallback());
    // 查詢安全單元服務的連接狀態(tài)
    boolean isConnected = sEService.isConnected();

     
    // 獲取本機的全部安全單元,并獲取指定的安全單元eSE
    Reader[] elements = sEService.getReaders();
    Reader eSe = null;
    for (int i = 0; i < elements.length; i++) {
        if ("eSE".equals(elements[i].getName())) {
            eSe = elements[i];
            break;
        }
    }

     
    // 查詢安全單元是否在位
    boolean isPresent = eSe.isSecureElementPresent();

     
    // 打開Session
    Optional<Session> optionalSession = eSe.openSession();
    Session session = optionalSession.orElse(null);

     
    // 打開通道
    if (eSe != null) {
        byte[] aidValue = new byte[]{(byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05};
        // 創(chuàng)建Aid實例
        Aid aid = new Aid(aidValue, 0, aidValue.length); 
        // 打開基礎通道
        Optional<Channel> optionalChannel = session.openBasicChannel(aid);
        Channel basicChannel = optionalChannel.orElse(null);
        // 打開邏輯通道
        optionalChannel = session.openLogicalChannel(aid);
        Channel logicalChannel = optionalChannel.orElse(null);

     
        // 發(fā)送指令給安全單元,返回值為安全單元對指令的響應
        byte[] resp = logicalChannel.transmit(new byte[]{(byte)0x00, (byte)0xa4, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00});

     
        // 關閉通道資源
        basicChannel.closeChannel()
        logicalChannel.closeChannel(); 
    }

     
    // 關閉Session資源
    session.close();

     
    // 關閉安全單元資源
    eSe.closeSessions();

     
    // 關閉安全單元服務資源sEService.shutdown();
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號