1. NFC开发(一)——HCE基于主机的卡模拟简述
许多提供NFC功能的基于android的设备已经支持NFC卡模拟。在大多数情况下,该卡由设备中的单独芯片模拟,称为 安全元件(Secure Element) 。无线运营商提供的许多SIM卡还包含安全元件(Secure Element)。
Android 4.4引入了另一种卡模拟方法,它不涉及SE,称为 基于主机的租芹卡模拟 。这允许任何Android应用程序模拟卡并直接与NFC读卡器通话。本文档描述了基于主机的卡肢型裂仿真(HCE)如何在Android上工作,以及如何使用此技术开发模拟NFC卡的应用程序。
当使用安全元件(Secure Element)提供NFC卡模拟时,将通过Android应用程序将要模拟的卡提供到设备上的安全元件(Secure Element)中。然后,当用户通过NFC终端握住设备时,设备中的NFC控制器将来自读卡器(NFC Reader)的所有数据直接路由到安全元件(Secure Element)。图1说明了这个概念。
安全元件(Secure Element)本身执行与NFC终端的通信,并且完全不涉及Android应用。交易完成后,Android应用程序可以直接查询SE的交易状态并通知用户。
当使用基于主机的卡仿真来仿真NFC卡时,数据将被路由到直接运行Android应用程序的主机CPU,而不是将NFC协议帧路由到SE。图2展示了基于主机的卡仿真如何工作。
NFC标准提供对许多不同协议的支持,并且可以模拟不同类型的卡。
Android 4.4支持当今市场上常见的几种协议。许多现有的非接触式卡已经基于这些协议,例如非接触式支付卡。这些协议也得到了当今市场上众多NFC读卡器的支持,其中包括Android NFC设备可以自己作为读卡器(请参见 IsoDep 课程)。这使您可以仅使用基于Android的设备在HCE周围构建和部署端到端NFC解决方案。
具体而言,Android 4.4支持基于NFC-Forum ISO-DEP规范(基于ISO / IEC 14443-4)的仿真卡,并处理ISO / IEC 7816-4规范中定义的应用协议数据历闭单元(APDU)。Android只强制在Nfc-A(ISO / IEC 14443-3 Type A)技术之上模拟ISO-DEP。支持Nfc-B(ISO / IEC 14443-4 Type B)技术是可选的。所有这些规格的分层如图3所示。
Android中的HCE体系结构基于Android Service 组件(称为“HCE服务”)。服务的一个关键优势是它可以在没有任何用户界面的情况下在后台运行。这对于许多HCE应用程序来说非常合适,例如会员卡或公交卡,用户不需要启动应用程序即可使用它。相反,通过NFC读卡器轻敲设备将启动正确的服务(如果尚未运行)并在后台执行该事务。当然,如果有意义的话,您可以自由地从您的服务中启动额外的UI(例如用户通知)。
当用户将设备连接到NFC读取器时,Android系统需要知道NFC读取器实际想要与哪个HCE服务通话。这就是ISO / IEC 7816-4规范的出处:它定义了一种选择应用程序的方式,以应用程序ID(AID)为中心。一个AID最多由16个字节组成。如果您正在模拟现有NFC读卡器基础架构的卡片,那么这些读卡器所寻找的AID通常是众所周知的并且是公开注册的(例如Visa和MasterCard等支付网络的AID)。
如果您想为自己的应用程序部署新的读卡器基础结构,则需要注册您自己的AID。AID的注册程序在ISO / IEC 7816-5规范中定义。如果您要为Android部署HCE应用程序,Google建议按照7816-5注册AID,因为它可以避免与其他应用程序发生冲突。
在某些情况下,HCE服务可能需要注册多个AID才能实现某个应用程序,并且需要确保它是所有这些AID的默认处理程序(而不是组中的某些AID转到其他服务) 。
一个AID组是应该被OS视为一起归属的AID列表。对于AID组中的所有AID,Android会保证以下其中一项:
换句话说,没有中间状态,组中的一些AID可以路由到一个HCE服务,另一些AID可路由到另一个。
每个AID组都可以与一个类别关联。这允许Android按类别将HCE服务组合在一起,并且反过来又允许用户在类别的级别而不是AID级别设置默认值。通常,避免在应用程序的任何面向用户的部分提及AID:它们对普通用户没有任何意义。
Android 4.4支持两种类别: CATEGORY_PAYMENT (涵盖行业标准支付应用程序)和 CATEGORY_OTHER (对于所有其他HCE应用程序)。
要使用基于主机的卡仿真来模拟NFC卡,您需要创建一个 Service 处理NFC事务的组件。
您的应用程序可以通过检查 FEATURE_NFC_HOST_CARD_EMULATION 功能来检查设备是否支持HCE 。您应该 <uses-feature> 在应用程序清单中使用该标记来声明您的应用程序使用HCE功能,以及该应用程序是否需要运行。
Android 4.4带有一个便利的 Service 类,可以作为实现HCE服务的基础: HostApService 类。
因此,第一步要扩大 HostApService 。
HostApService 声明了两个需要重写和实现的抽象方法。
processCommandAp() 只要NFC读卡器将应用协议数据单元(APDU)发送到您的服务,就会调用它。APDU也在ISO / IEC 7816-4规范中定义。APDU是在NFC读卡器和您的HCE服务之间交换的应用级数据包。该应用级协议是半双工的:NFC读卡器会向您发送命令APDU,并等待您发送响应APDU作为回报。
如前所述,Android使用AID来确定读者想要与哪个HCE服务交谈。通常,NFC读卡器向您的设备发送的第一个APDU是“SELECT AID”APDU; 这个APDU包含读卡器想与之交谈的AID。Android从APDU中提取AID,将其解析为HCE服务,然后将该APDU转发给已解析的服务。
您可以通过返回响应APDU的字节来发送响应APDU [processCommandAp()]( https://developer.android.com/reference/android/nfc/cardemulation/HostApService.html#processCommandAp(byte[] , android.os.Bundle))。请注意,此方法将在应用程序的主线程中调用,该线程不应被阻止。所以如果你不能立即计算并返回一个响应APDU,那么返回null。然后,您可以在另一个线程上完成必要的工作,并 sendResponseAp() 在完成后使用 HostApService 该类中定义的方法发送响应。
Android会继续将新的APDU从读取器转发到您的服务,直到:
在这两种情况下,你的类的 onDeactivated() 实现都是通过一个参数来调用的,这个参数指出了两者中的哪一个发生了。
如果您正在使用现有的读卡器基础架构,则需要实现读卡器在您的HCE服务中期望的现有应用程序级协议。
如果您正在部署您控制的新读卡器基础架构,则可以定义自己的协议和APDU序列。通常,尝试限制APDU数量和需要交换的数据大小:这样可以确保用户只需将设备通过NFC读取器持续一段时间即可。合理的上限约为1KB的数据,通常可以在 300ms 内交换。
您的服务必须像往常一样在清单中声明,但还必须在服务声明中添加一些附加件。
首先,为了告诉平台它是一个实现 HostApService 接口的HCE服务 ,你的服务声明必须包含一个 SERVICE_INTERFACE 动作的 Intent Filter 。
另外,为了告知平台哪个AIDs组被这个服务请求,一个 SERVICE_META_DATA <meta-data> 标签必须包含在服务的声明中,指向一个XML资源和关于HCE服务的附加信息。
最后,您必须将该 android:exported 属性设置为true,并且 "android.permission.BIND_NFC_SERVICE" 在服务声明中要求权限。前者确保服务可以被外部应用程序绑定。后者然后强制只有拥有该 "android.permission.BIND_NFC_SERVICE" 权限的外部应用程序 才能绑定到您的服务。既然 "android.permission.BIND_NFC_SERVICE" 是一个系统权限,这有效地强制只有Android OS可以绑定到你的服务。
这是一个 HostApService 清单声明的例子:
这个元数据标签指向一个 apservice.xml 文件。下面显示了具有包含两个专有AID的单个AID组声明的此类文件的示例:
该 <host-ap-service> 标签需要包含一个 <android:description> 属性,该属性包含可能在UI中显示的用户友好的服务描述。该 requireDeviceUnlock 属性可用于指定在调用此服务来处理APDU之前必须先解锁设备。
在 <host-ap-service> 必须包含一个或多个 <aid-group> 标签。每个 <aid-group> 标签都需要:
最后,您的应用程序还需要拥有 NFC 可以注册为HCE服务的 权限。
多个 HostApService 组件可以安装在单个设备上,并且可以由多个服务注册相同的AID。Android平台根据AID属于哪个类别来解决AID冲突。每个类别可能有不同的冲突解决策略。
例如,对于某些类别(如付款),用户可能能够在Android设置UI中选择默认服务。对于其他类别,策略可能总是要求用户在冲突情况下调用哪个服务。要查询特定类别的冲突解决策略,请参阅 getSelectionModeForCategory() 。
应用程序可以使用[isDefaultServiceForCategory(ComponentName, String)]( https://developer.android.com/reference/android/nfc/cardemulation/CardEmulation.html#isDefaultServiceForCategory(android.content.ComponentName , java.lang.String))API 检查其HCE服务是否是某个类别的默认服务。
如果您的服务不是默认设置,则可以请求将其设置为默认设置。看 ACTION_CHANGE_DEFAULT 。
Android会将AID组为“payment”的类别,声明的HCE服务视为支付应用程序。Android 4.4版本包含一个名为“tap&pay”的top-level设置菜单条目,它列举了所有这些支付应用程序。在此设置菜单中,用户可以选择在点按付款终端时将调用的默认支付应用程序。
为了提供更具视觉吸引力的用户体验,HCE支付应用程序需要为其服务提供额外的resource:所谓的服务标记。
这个asset的大小应该是260x96 dp,并且可以在元数据(meta-data)XML文件中通过添加指向drawable resource android:apServiceBanner 的 <host-ap-service> 标签的属性来指定 。一个例子如下所示:
当设备的屏幕关闭时,当前的Android实施将NFC控制器和应用程序处理器完全关闭。因此,当屏幕关闭时,HCE服务将无法工作。
然而,HCE服务可以从锁定屏幕中起作用:这由HCE服务标记中的 android:requireDeviceUnlock 属性控制 <host-ap-service> 。默认情况下,不需要设备解锁,即使设备被锁定,您的服务也会被调用。
如果您将 android:requireDeviceUnlock HCE服务的属性设置为“true”,Android会提示用户在您靠近NFC读卡器时解锁设备,NFC读卡器会选择已解析为您的服务的AID。解锁后,Android会显示一个对话框,提示用户再次点击以完成交易。这是必要的,因为用户可能已经将设备从NFC读卡器移开以便解锁它。
本部分对于已经部署依赖SE进行卡模拟的应用程序的开发人员很感兴趣。Android的HCE实现旨在与其他实现卡仿真的方法并行工作,包括使用SE。
这种共存基于一种称为“AID路由”的原则:NFC控制器保留一个由(有限)路由规则列表组成的路由表。每个路由规则都包含一个AID和一个目的地。目标可以是主机CPU(Android应用程序正在运行的地方),也可以是连接的SE。
当NFC读卡器发送具有“SELECT AID”的APDU时,NFC控制器解析它并检查AID是否与其路由表中的任何AID匹配。如果匹配,那么APDU和其后的所有APDU将被发送到与AID相关联的目的地,直到收到另一个“SELECT AID” APDU或NFC链路断开。
图4说明了这种架构。
NFC控制器通常还包含APDU的默认路由。在路由表中找不到AID时,将使用默认路由。尽管此设置可能因设备而异,但Android设备需要确保您的应用注册的AID已正确路由到主机。
实现HCE服务或使用SE的Android应用程序不必担心配置路由表 - 这是由Android自动处理的。Android只需要知道哪些AID可以由HCE服务处理,哪些可以由SE处理。基于哪些服务已安装,以及哪些用户已配置为首选服务,路由表会自动配置。
我们已经介绍了如何声明HCE服务的AID。以下部分说明如何为使用SE进行卡模拟的应用程序声明AID。
使用SE进行卡模拟的应用程序可以在其清单中声明所谓的“关闭主机服务”。这种服务的声明几乎与宣布HCE服务相同。以下情况例外:
相应 apservice.xml 文件注册两个AID 的示例:
该 android:requireDeviceUnlock 属性不适用于脱离主机服务,因为主机CPU不参与事务,因此无法阻止SE在设备锁定时执行事务。
该 android:apServiceBanner 属性必须用于作为支付应用程序的关闭主机服务,以便作为默认支付应用程序进行选择。
Android本身永远不会启动或绑定到声明为“脱离主机”的服务。这是因为实际交易由SE执行,而不是由Android服务本身执行。服务声明仅允许应用程序注册安全元件(Secure Element)上存在的AID。
HCE体系结构本身提供了一个核心安全性:因为您的服务受到 BIND_NFC_SERVICE 系统权限的保护,所以只有操作系统可以绑定到您的服务并与之通信。这可以确保您收到的任何APDU实际上都是OS从NFC控制器接收到的APDU,并且您发回的任何APDU只会发送到操作系统,而操作系统会直接将APDU转发给NFC控制器。
剩下的核心部分就是您获取应用程序发送给NFC读卡器的数据的位置。这在HCE设计中有意解耦:它不关心数据来自何处,它只是确保将其安全地传送到NFC控制器并传送到NFC读取器。
为了安全地存储和检索您希望从HCE服务发送的数据,例如,您可以依靠Android应用程序沙箱,将应用程序的数据与其他应用程序隔离。有关Android安全性的更多详细信息,请阅读 安全提示 。
这部分内容对于希望了解HCE设备在NFC协议的防冲突和激活阶段使用何种协议参数的开发人员很感兴趣。这允许构建与Android HCE设备兼容的读卡器基础结构。
作为Nfc-A协议激活的一部分,交换多个帧。
在交换的第一部分,HCE设备将呈现其UID; HCE设备应该被假定为具有随机的UID。这意味着在每个抽头中,呈现给读卡器的UID将是随机生成的UID。因此,NFC读卡器不应依赖HCE设备的UID作为身份验证或身份验证的一种形式。
NFC读取器可以随后通过发送SEL_REQ命令来选择HCE设备。HCE设备的SEL_RES响应将至少设置第6位(0x20),表示设备支持ISO-DEP。注意,SEL_RES中的其他位也可以被设置,表示例如对NFC-DEP(p2p)协议的支持。由于可以设置其他位,所以想要与HCE设备交互的读者应该明确检查第6位,并且<stront style="box-sizing: inherit;">不要将完整的SEL_RES与值0x20进行比较。</stront>
Nfc-A协议激活后,NFC读取器启动ISO-DEP协议激活。它发送一个“RATS”(请求选择应答)命令。RATS响应(ATS)完全由NFC控制器生成,不能由HCE服务配置。然而,HCE实现需要满足NFC论坛对ATS响应的要求,因此NFC读卡器可以根据NFC论坛对任何HCE设备的要求设置这些参数。
以下部分提供了有关NFC控制器在HCE设备上提供的ATS响应的各个字节的更多详细信息:
请注意,许多HCE设备可能符合EMVCo联合的支付网络在其“非接触式通信协议”规范中指定的协议要求。尤其是:
如前所述,HCE实现仅支持单个逻辑通道。尝试在不同的逻辑通道上选择应用程序将不适用于HCE设备。
本文 翻译自 谷歌开发者文档,已由本人仔细校对。如有错误,请联系我,以便修改。
2. 感应式读卡器,复制你的门禁卡、购物卡、饭卡,你的卡还安全么
看了这个,你的饭卡还安全吗?
仅供测试,请勿模仿。
//NFC是什么,肯德基吗,,,不。。。
近场通信(Near Field Communication,简称NFC),是一种新兴的技术,使用了NFC技术的设备
(例如移动电话)可以在彼此靠近的情况下进行数据交换,是由非接触式射频识别(RFID)及 互连 互通技术整合演变而来的,通过在单一芯片上集成感应式读卡器、感应式卡片和点对点通信的功能,利用移动终端实现移动支付、电子票务、门禁、移动身份识别、防伪等应用。由飞利浦公司和索尼公司共同开发的一种非接触式识别和互联技术,可以在移动设备、消费类电子产品、PC和智能控件工具间进行近距离无线通信。NFC功能提供了一种简单、触控式的解决方案,可以让消费者简单直观地交换信息、访问内容与服务。
借助CM9 rom的nfc读写标签功能,实现软件卡模拟。(之前的版本都没有,google官方版本没有开放此功能,目前从android 5.0起google开放了其他nfc api以进行卡模拟操作,)。
手机或手环等带有NFC功能的设备通过模拟IC卡的操作,把像小区门禁卡、饭卡等IC卡的数据复制到手机的NFC芯片上面,以后就可以用手机的NFC功能进行刷卡。
可以截获安卓手机支持的13.56hz nfc无线通讯协议的所有标签数据,nfc非接触黑盒测试一直没有太好的方案,要么太高端(需要专业的设备),要么不好用(proxmark3也不便宜,监听无线的方式导致截获数据不稳定,也没有现成儿的解决方案,操作的便捷性和交互性也好差)nfcproxy给我们这些偶尔用一用的测试狗提供了一种低成本高效率的解决方案,支持各种nfc标签,iso 14443标准,ap数据也是完整稳定的,基于安卓app源码的二次开发也非常简单,会java的随便改改基本都不是问题。基于这个 app可以以软件方式衍生出多种测试方式
1、 卡和终端之间数据的嗅探
2、 交互过程中的数据修改
3、 模拟卡
最关键的还是简单,买俩一百来块钱一个的二手手机就可以了。
硬件需求:
两个带nfc功能的android手机(咸鱼最便宜300块钱以内可以搞定)一个带非接触功能的POS或者读卡器(有个pos最省事,我有一个支持银联闪付的pos)自己的银行卡,支持非接触支付的,有银联quick pass标志的都可以
1、基于支持CM9 rom的安卓手机一个
我用的是谷歌亲儿子一代 nexus s,ROM是slim 4.3 build 2-OFFICIAL-1332 一个基于cm的定制版本
android版本 4.3.1。我买得早,略贵,现在闲鱼买二手的话没有必要买这个,后面几代也都便宜了,二儿子三儿子四儿子什么的,都可以考虑,一加一也可以考虑,略贵。理论上支持CM9的都可以,但由于
CM官网已经黄了老版本的rom不好找,所以尽量要先找到手机对应的老版本的rom再决定买啥。 2、带nfc功能的安卓手机一个(最好也支持cm9)
我用的是 三星 GALAXY S2的T版SGH-T989大力神,CM版本是11-20160815-NIGHTLY-hercules,
android版本4.4.4 ,cm11好像已经去掉软件卡模拟的功能了,我也没有去降rom版本,有一个能用行了。只要不是太奇葩的定制rom,理论上都可以。建议还是选择支持cm的,比较保险。硬件选择同上软件需求:
有完整的功能实现,大家可以直接打包使用我基于自己用着方
便,整合了emv-bertlv库,可以直接在app里把交互数据拆包。大家可以用着试试我的github地址:
本地app包下载:
使用方法
两个手机都安装nfcproxy都打开NFC功能连接到同一个wifi,两个手机之间可以相互访问
1、 proxy端设置
在支持cm9卡模拟的手机(我得是nexus s),打开nfcproxy软件,点设置,取消 relay mode 单选框IP 地址填另一个手机的wifi ip端口 填另一个手机的nfcproxy监听端口,默认9999encrypt
communications 不需要选,自己玩不用加密always keep screen on 随便debug logging 勾上,可以显示出卡号。然后退出设置。
2、 relay端的设置
在另外一个手机(我得是t989),打开nfcproxy软件,点设置,勾选 relay mode 单选框IP 地址 不用填
端口 填刚刚在另一个手机设置的nfcproxy监听端口,默认9999,两边一样就行encrypt
communications 不需要选,自己玩不用加密always keep screen on 随便debug logging 勾上,可以显示出卡号。然后退出设置。
3、 测试
1、 将用于relay端的手机,nfcproxy软件打开贴到银行卡上,这时status窗口应该提示
TechList:android.nfc.tech.IsoDepandroid.nfc.tech.NfcA,如果没反应请检查nfc是否打开,手机
NFC功能是否正常
2、 将POS机弄到选择消费,输入金额后,提示请刷卡的界面
3、 将用于proxy端的手机,nfcproxy软件打开,去贴到POS机上执行非接刷卡动作。
正常情况贴上去后nfcproxy的data窗口会提示:Reader
TAG:Tech[android.nfc.tech.Iso.PcdA]Connecting to NFCRelayConnected to NFCRelayTransaction
Complete!这说明已经已经连上了贴卡那台手机,POS机的请求已经转发到卡上了,并且卡的应答已经转发回来了,交易成了。这时候POS应该显示请输入密码了,输入密码交易成功。再看replay端的 nfcproxy的data窗口,就可以看到交互的数据了在数据上长按可以选择最右面的三个竖点,export to file将截取的数据保存到内部存储的/NfcProxy目录中
注1:如果帖POS的手机没反应,需要检查nfc功能是否正常
注2:status 提示 connection to NFCRelay failed 需要检查两台手机wifi是否联通,配置的ip和端口是否正常
祝好运。
btw: 这个方案15年我就在用,只是工作测试pos需要,偶尔用到感觉很方便,最近又用了一次,下决心整理一下。之前都看大神的文章,自己也为社区贡献一次。软件本身还有很大潜力可以挖,比如动态修改交互数据什么的。。。。。。 你们懂的,不要乱来哦,会查水表的。 另外也发现有一些终端读卡会采用一些奇怪的模式,导致软件报错,这时候只能再用proxmark3暴力监听了,但这个mitm的方式比 proxmark方便多了,也便宜的多了哈。最后附一张ppt里的图,我简单画了一下,方便大家理解
在复制IC卡这一块,我把IC卡分为加密卡和非加密卡两类,非加密卡请直接尝试复制,不行的话参照加密卡的教程。
工具:
1.硬件:PN532(初学者建议购买这个,某宝卖30RMB左右,一般的半加密卡用这个就能破解了,全加密卡需要用到PM3),USB转ttl线,小米手环NFC版(3代4代随意),cuid卡
2.软件:PN532的驱动(自己问卖家要,找对应的驱动,或看看我链接里的驱动适不适合)、winhex、
MifareOneTool(简称M1T)、NFC_READER_crack。
首先把USB转ttl线与PN532连接好(线序定义:黑GND, 红VCC,白SDA,绿SCL)。然后在电脑安装好
PN532的驱动,PN532连接到电脑,然后查看设备管理器,COM口那有设备证明已经成功安装好驱动了。
打开M1T软件,点击检测连接然后一键解原卡,有密钥的会尝试破解,破解成功后会导出一个.mp文件,我们把它保存。
用winhex打开该.mp文件,把AB密钥用FF填充,填充好了之后我们另存为一份,顺便把开头的卡号记下来(8位)
之后我们再次打开M1t,选择高级操作模式,打开Hex编辑器,把刚刚找的八位卡号复制下来,再打开工具,修改UID,把刚才复制的八位卡号粘贴到里面,点确定,然后点文件-另存为一个.mfd文件。
高级模式里选择cuid写,把刚刚的.mfd文件写入cuid卡里面,如果没写满64个块就再写一次。
小米手环选择门卡模拟,把刚刚写入了.mfd文件的cuid卡模拟到小米手环上,之后打开
NFC_READER_crack这个软件,选择写普通M1卡,把填充好密钥的饭卡数据写入手环中。如果只写入63个块,那也没关系,去试试能不能用。
然后就大功告成啦!!
本教程切勿用于非法用途,复制饭卡余额都是一样的,不存在修改余额这一说。饭卡原本余额是多少的,你用什么来打饭余额都是一样。复制到手环里只是为了方便打饭。
Q:为什么到了最后把数据写入手环时不用原来的M1T而是用NFC_READER_crack呢?
A:因为用M1T写入数据到手环会出现玄♂学问题,就是写不到63个块,用NFC_READER_crack就没有问题。如果是用cuid卡来复制门禁卡的话可以尝试用M1T。
Q:那如何复制门禁卡?
A:门禁卡如果是半加密卡的话可以参照本文来复制,如果是非加密卡的话试试直接模拟可不可以,如果不行的话按照读出数据(保存)–生成一个带有卡号的.mfd文件–复制到cuid卡–手环模拟该cuid卡–手环写入门禁卡数据这一步骤来复制。
生活中不乏其他案例,黑客破解NFC公交卡,可无限次乘车,甚至可以劫持带有NFC功能的手机,所以安全问题显而易见,毕竟防人之心不可无。