场景介绍
应用或者其他模块可以通过接口完成以下功能:
- 获取安全单元的个数和名称。
- 判断安全单元是否在位。
- 在指定安全单元上打开基础通道。
- 在指定安全单元上打开逻辑通道。
- 发送 APDU(Application Protocol Data Unit)数据到安全单元上。
接口说明
类名 |
接口名 |
功能描述 |
SEService |
SEService() |
创建一个安全单元服务的实例。 |
isConnected() |
查询安全单元服务是否已连接。 |
|
shutdown() |
关闭安全单元服务。 |
|
getReaders() |
获取全部安全单元。 |
|
getVersion() |
获得安全单元服务的版本。 |
|
OnCallback |
用于回调的内部类,用于定义回调接口。在服务连接成功后,回调该接口通知应用。 |
|
Reader |
getName() |
获取安全单元的名称。 |
isSecureElementPresent() |
检查安全单元是否在位。 |
|
openSession() |
打开当前安全单元上的 session。 |
|
closeSession() |
关闭当前安全单元上的所有 session。 |
|
Session |
openBasicChannel(Aid aid) |
打开基础通道。 |
openLogicalChannel(Aid aid) |
创建逻辑通道。 |
|
getATR() |
获得重设安全单元指令的响应。 |
|
closeSessionChannels() |
关闭当前 session的所有通道。 |
|
Channel |
isClosed() |
判断通道是否关闭。 |
isBasicChannel() |
判断是否是基础通道。 |
|
transmit(byte[] command) |
发送指令到安全单元。 |
|
getSelectResponse() |
获得应用程序选择指令的响应。 |
|
closeChannel() |
关闭通道。 |
|
Aid |
Aid(byte[] aid, int offset, int length) |
构造一个 AID 类的实例。 |
isAidValid() |
查询AID是否有效。 |
|
getAidBytes() |
获取AID的字节数组形式的值。 |
|
开发步骤
- 调用 SEService 类的构造函数,创建一个安全单元服务的实例,用于访问安全单元。
- 调用 isConnected() 接口,查询安全单元服务的连接状态。
- 调用 getReaders() 接口,获取本机的全部安全单元。
- 调用 Reader 类的 openSession() 接口打开 Session,返回一个打开的 Session 实例。
- 调用 Session 类的 openBasicChannel(Aid aid) 接口打开基础通道,或者调用 openLogicalChannel(Aid aid) 接口打开逻辑通道,返回一个打开通道 Channel 实例。
- 调用 Channel 类的 transmit(byte[] command),发送 APDU 到安全单元。
- 调用 Channel 类的 closeChannel() 接口关闭通道。
- 调用 Session 类的 closeSessionChannels() 接口关闭 Session 的所有通道。
- 调用 Reader 类的 closeSessions() 接口关闭安全单元的所有 Session。
- 调用 SEService 类的 shutdown() 接口关闭安全单元服务。
private class AppServiceConnectedCallback implements SEService.OnCallback {
@Override
public void serviceConnected() {
// 应用自实现
}
}
// 创建安全单元服务实例
SEService sEService = new SEService(context, new AppServiceConnectedCallback());
// 查询安全单元服务的连接状态
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};
// 创建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);
// 发送指令给安全单元,返回值为安全单元对指令的响应
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();
请发表评论