美文网首页
OpenMobileAPI、OMA总结

OpenMobileAPI、OMA总结

作者: inlooker | 来源:发表于2021-09-07 15:30 被阅读0次

    前言:现在工作的主要内容是关于SDK相关方面开发,而现在的公司的业务绝大多数是关于OpenMobileAPI相关。所以工作的内容就是做关于智能卡相关的SDK项目,写下这篇文章是对近一年工作的总结也是一种记录。自己认识的不足与可能存在的错误,权当是学艺不精吧!

    OMA是什么?

    开放移动联盟 (OMA) 是一个为移动电话行业开发开放标准的标准机构。它不是像国际电联这样正式的政府赞助的标准组织,而是行业利益相关者就产品和服务的通用规范达成一致的论坛。
    维基百科关于OMA
    simalliance官网
    GitHub地址

    涉及场景及用途

    在Android客户端主要涉及手机、Sim卡,或者其他一些带有SE安全芯片的设备。其主要应用场景是城市公交、地铁、门禁、或者是需要用到身份认证的且对安全级别有一定要求的业务。
    现在智能手机上手机自带的一些交通卡方案,通过NFC进行地铁、公交、门禁等使用。其中读取的安全模块有两种,一种是eSE,也就是手机内嵌安全芯片。另外一种就是通过读取卡槽中的SIM卡上内嵌的安全芯片。这些安全芯片有独立内存、计算能力等可以进行Applet安装与个人化等一些列操作。

    特别说明

    特别需要说明的一点是,在Android P以后,谷歌将此API的实现纳入官方API中。所以在Android P之前需要外部引入org.simalliance.openmobileapi.jar包才能使用相关功能。Android P及以后的版本可以直接从android.se.omapi位置导入相关类。

    使用过程

    1.获得SEService对象;

    //在org.simalliance.openmobileapi.SEService里获取
    SEService mSEService = new SEService(Context context, SEService.OnConnectedListener listener);
    //在android.se.omapi.SEService里获取
    SEService mSEService = new SEService(Context context, Executor executor, SEService.OnConnectedListener listener);
    //传入的参数略有不同。
    

    2.通过获得的SEService对象得到Reader,既mSEService.getReaders();

    Reader[] readers = mSEService.getReaders();
    //获得的是一个Reader[]在这里就可以对要操作的不用种类的SE安全模块进行区分了。
    String readerName = reader.getName();
    //可以获取本reader的名字进而选自自己所做业务所需reader类型。
    //需要注意的是
    boolean b = reader.isSecureElementPresent();
    //可以获取当前选择的reader是否可用,之所以需要进行判断是因为,在某些情况下卡是无法访问的。
    //比如在遇到AccessControl权限问题是就是无法访问。这是因为所选。
    

    3.通过选择的Reader获取Session,既reader.openSession();

    Session mSession = reader.openSession();
    

    4.Session开通道,也就是访问模块中指定的某些区域。

    Channel mChannel = mSession.openLogicalChannel(byteAid);
    //注意:这里进行开通道所传的参数不是字符串而是一个十六进制byte[],
    //在做这个操作时的byte[]就是访问安全域或者是SE上应用的id。
    //api使用的是十六进制byte[],也就是APDU,最小指令单元。
    //为了方便开发时对所操作的指令进行查看,一般都是指令String,所以需要byte[]与String之间的切换。
    

    5.进行指令交互,将指令依次传到所访问的模块或应用里,交给SE处理。

     byte[] byteRapdu = mChannel.transmit(byteCommand);
     //这里同Session开通道一样所需要的都是byte[],同样卡片吐回的也是byte[]。
     //然后就是根据自己业务需要对所返回的APDU进行分析处理。
    

    6.在一个业务完成之后需要进行关闭通道操作。

    mChannel.close();
    mSession.close();
    //开通道时有指定id进行操作,关闭时只需要将之前的channel和session进行关闭就好。
    //系统会自动关闭当前开启的通道。
    //之所要做这一步操作是因为在本次业务完成之后,如果需要进行选择别的通道进行相应业务,
    //而这时如果没有关闭的话会导致新的通道无法打开等异常。
    

    7.全部业务或者是程序退出时进行SEService释放

     mSEService.shutdown();
     //这一步SEService释放不建议在小业务完成时就进行释放,因为这样会面临频繁的服务连接。
    

    以上就是OMA的简要使用过程。总结一句话就是开通道、传指令、关通道。

    注意事项

    1.关于APDU
    在进行APDU指令交互的过程中返回的APDU指令是由多部分组成,对于客户端需要注意的是最后四位也就是SW,状态字。状态字是对所传到卡里边的APDU处理之后的一个响应状态代码。
    常见APDU响应状态字SW

    2.关于AccessControl权限错误,无法访问所指向的卡。
    出现这种错误的原因是因为,在访问卡的时候没有相应的访问卡的权限。这是一种卡应用保护机制,不是所有应用(Android APP)都可以访问卡里边某些应用(卡应用Applet)。
    有些卡是AC全开放,也就是只要通过OMA就可以访问这张卡。有些是AC指定开发,这就需要在发卡的时候提前在卡里写入访问者的Hash签名值,这样在访问卡时才能进行顺利访问。

    最后可以访问我的github里边有封装好的OMA使用:
    ShinlookerGitHub-SmartCard

    如果想了解更多关于OMA卡相关,可以下载GP规范中文版。里有关于卡的全面介绍与更详细的说明。
    GP卡开发规范说明书_中文版

    以上便是OMA基本的使用逻辑与注意事项,有很多不足请多多指教。
    ------咱们来日方长。

    相关文章

      网友评论

          本文标题:OpenMobileAPI、OMA总结

          本文链接:https://www.haomeiwen.com/subject/kacpwltx.html