在Android中访问内置SE和基于SE的卡模拟(二)

来源:互联网 发布:中国历年通胀率数据 编辑:程序博客网 时间:2024/05/21 14:51

改变SE工作模式

在NfcAdapterExtras类中,有两个关于卡模拟的函数,getCardEmulationRoute和setCardEmulationRoute,分别用于得到和设置卡模拟工作模式,其中getCardEmulationRoute返回一个CardEmulationRoute类对象,而setCardEmulationRoute需要构造一个CardEmulationRoute类对象作为参数。

CardEmulationRoute类为NfcAdapterExtras中定义的内部类,主要包括:

 NfcExecutionEnvironment

     nfcEe 
          The NFcExecutionEnvironment that is Card Emulation is routed to.

 int

     route 
          A route such as ROUTE_OFF or ROUTE_ON_WHEN_SCREEN_ON.

 

由于CardEmulationRoute是一个内部类,我们甚至不能用类名反射得到类定义,只能从NfcAdapterExtras类中提取,由于NfcAdapterExtras中只有一个内部类,我们可以简单的取第一个即可。通过构造CardEmulationRoute类,可以将相关SE设置为ROUTE_OFF或ROUTE_ON_WHEN_SCREEN_ON,即卡模拟关闭和卡模拟在屏幕开启时打开。以下 具体的实现:

int  routeOption = ROUTE_ON_WHEN_SCREEN_ON;

 //Get route inner class

Class nfcAdapterExtrasClazz =Class.forName("com.android.nfc_extras.NfcAdapterExtras");

Class[]  innerClazz =nfcAdapterExtrasClazz.getDeclaredClasses();

Constructor clazzConstuctor = innerClazz[0].getConstructor(Integer.TYPE,Class.forName("com.android.nfc_extras.NfcExecutionEnvironment"));

Object route = clazzConstuctor.newInstance(routeOption, se);

 //Setcard emulation route

Method setCardEmulationRouteMethod = nfcExtras.getClass().getMethod("setCardEmulationRoute",innerClazz[0]);

setCardEmulationRouteMethod.invoke(nfcExtras,route);

 

通过这些代码,我们可以将得到的SE(NFcExecutionEnvironment)设为卡模拟模式,

 

 

 

相应的,通过

int routeOption = ROUTE_OFF;

Object route =clazzConstuctor.newInstance(routeOption, null);

setCardEmulationRouteMethod.invoke(nfcExtras,route);

 

可以关闭卡模拟模拟。



如果不进行模式设置,使用getCardEmulationRoute得到的CardEmulationRoute中,NFCEE为空,状态为ROUTE_OFF,可见缺省状态下,卡模拟为关闭,且不关联到任何NFCEE上。

 

Object cardEmulationRoute = getCardEmulationRouteMethod.invoke(nfcExtras, null);

Field route = cardEmulationRoute.getClass().getDeclaredField("route");

Object r= route.get(cardEmulationRoute);

return Integer.parseInt(r.toString());

 

为了检查手机是否真正工作在卡模式下,我们需要一个读写器。注意不能用另外一个NFC手机,因为NFC手机之间总是优先使用NFC的P2P模式,而不会使用读写器-卡模式工作。

以下是使用读写器读取的例子

GALAXY NEXUSI9250                           

ISO/IEC 14443A(106 kbps) target:                                                                              

ATQA (SENS_RES):00  02                                                                                     

UID (NFCID1):2f  8a c6  99                                                                               

SAK (SEL_RES):38                                                                                            

ATS: 78  80 70  02  00 31  c1  73 c8  40  00 00  90  00     

可见模拟卡的UID为2f 8a c6 99,符合ISO14443-4协议。

 

再选择空的AID,能够得到从内部访问同样的GP数据。

[root@TestAgmnewDisk]# ./readnfccc

SELECT_APP-------------------------106

< 6f658408a000000003000000a5599f6501ff9f6e06479100783300734a06072a864886fc6b01600c060

a2a864886fc6b02020101630906072a864886fc6b03640b06092a864886fc6b040215650b06092b8510

864864020103660c060a2b060104012a026e01029000

 

在SE中添加应用以实现自己的卡模拟

         既然我们建立了与SE的连接,是否就可以安装应用了呢?当然不是,如果这样,SE也没有安全性可言了。前面提到SE是一个CPU卡,一般符合GP标准。GP标准的目的就是支持卡上的多应用的同时,保证卡内容的安全。

SE的发行者拥有GP卡管理器的密钥,即主安全域(ISD)密钥,可以进行辅助安全域和应用的创建和安装。

为了让不同的应用提供商都可以使用SE上的空间,应用提供商可以向SE发行者申请,建立辅助安全域,并通过密钥转换,控制一部分SE空间,并进行应用的下载/更新/删除。为了在后台自动完成这些流程,就需要一个代理中介实现,即所谓的授信服务管理器(Trusted Service ManagerTSM)。SE发行者通过建立发行者TSM(SE-TSM),提供对其拥有的SE的操作。应用提供商通过与SE发行者的达成合作协议,实现自己应用的下载安装。

 

因此,目前有以下几种方式可以获得在SE上安装应用的权力:

1,  自行发卡,自己控制SE的主密钥。

2,  从SE发行者得到密钥,在一般情况下,SE发行者是不可能提供这些密钥的,但是有些开发测试机是公开密钥的,以便提供给应用合作伙伴进行测试。

3,  不获取密钥,而是通过SE-TSM代理完成。

4,  破解,但由于SE一般有自锁功能,因此暴力破解是很困难的。

 

OK,感谢你看完这篇晦涩的文章,希望能有所帮助,如果有错误,请指正。本文主要参考:

http://nelenkov.blogspot.com/2012/08/accessing-embedded-secure-element-in.html

http://nelenkov.blogspot.com/2012/08/android-secure-element-execution.html

http://wiki.yobi.be/wiki/Android_SE

https://code.google.com/p/seek-for-android/

原创粉丝点击