NFC卡研究笔记

一. NFC卡基础单词了解


 sector扇区
 block块


二.采购卡片信息


把卡一直放后面读设备会发热

09(CPU卡)
 android.nfc.tech.IsoDep, android.nfc.tech.NfcA
10(CPU的7K加M1的1K)
 会读到android.nfc.tech.IsoDep, android.nfc.tech.NfcA和android.nfc.tech.IsoDep, android.nfc.tech.NfcA, android.nfc.tech.NfcA, android.nfc.tech.MifareClassic, android.nfc.tech.NdefFormatable,中任意一种。第二种其实包含第一种的两个情况的。说明第一种的是没读取全。这个等于是09的加23的所以NfcA是重复的。
23 (S70的4K加CPU的4K)
 android.nfc.tech.NfcA,android.nfc.tech.MifareClassic,android.nfc.tech.NdefFormatable,
 S70的23卡会被格式化为NDEF。被NDEF后就可恢复出厂设置。会被格式化为NDEF就不行的Cpu的09卡,暂时对cpu类型的没研究。m1的10卡,不会被格式化,恢复出厂虽然现实成功,但数据还在。


三.卡数据读取


卡使用的技术包括

mTechLists = new String[][] { 
new String[] { NfcF.class.getName() }, 
new String[] { NfcA.class.getName() }, 
new String[] { NfcB.class.getName() }, 
new String[] { NfcV.class.getName() }, 
new String[] { Ndef.class.getName() }, 
new String[] { NdefFormatable.class.getName() }, 
new String[] { IsoDep.class.getName() }, 
new String[] { MifareClassic.class.getName() }, 
new String[] { MifareUltralight.class.getName() } }; 

CPU卡对应识别的是IsoDep,m1卡对应的是NfcA。从记录0采购卡片信息中可以看出一种卡包含很多种呀。
NFC三重过滤机制。
(1)NDEF_DISCOVERED: 只过滤固定格式的NDEF数据。例如:纯文本、指定协议(http、ftp、smb等)的URI等;
(2)TECH_DISCOVERED: 当ACTION_NDEF_DISCOVERED指定的过滤机制无法匹配Tag时,就会使用这种过滤机制进行匹配,这种过滤机制并不是通过Tag中的数据格式进行匹配的,而是根据Tag支持的数据存储格式进行匹配,因此这种过滤机制的范围更广;
(3) TAG_DISCOVERED: 如果将NFC过滤机制看成if...else if...else语句的话,那么这种过滤机制就相当于else部分,当前面两种过滤机制都匹配失败后,系统就会利用这种过滤机制来处理,这种过滤机制用来处理未识别的Tag(数据格式不对,而且Tag支持的格式也不匹配)。

四.下载软件android-filechooser.apk即nfc写卡软件。


 发现23卡可被擦写格式化为NDEF卡,09和10不行提示有保护。应该是S70的那部分问题。也可通过代码的写操作变成NDFF卡。23卡转换为NDFF卡后所有扇区验证都失败了

五.使用擦写为出厂设置就会恢复初始了,所以不用怕测试操作导致卡不能用。(前提这个卡,可擦写。10好像擦了也没改变,可能是密码我改过吧)。


六.cpu的扇区是读取不出来的。或者其压根没有扇区概念


 有些扇区可能会验证失败原因是密码A或者B错误。 M1的S70卡4K字节, 共40个扇区,前32个扇区中,每个扇区4个数据块,每个数据块16个字节,后8个扇区中,每个扇区16个数据块,每个数据块16个字节;我的那张卡后8个扇区会验证失败 M1卡1k字节。共16个扇区,每个扇区4个数据块

七.数据块说明之MifareClassic卡通过Access Bits来控制keyA和keyB的读写权限


 扇区和数据块都是0开始算的。第一个扇区自然指0了。但扇区的块编号是即使扇区改变也一直递增的。获取mfc.sectorToBlock(SectorPos)//获取扇区第一个块编号加上读取块是第几个块就是读取块编号。

 0扇区的0块(Manufacturer Blcok)由厂商使用,存储了IC卡的生产产商代码,前4个字节(即8个数字)是卡号。第5个字节是校验位,后面的是生产商数据。

 其他扇区的第0块没存东西。第0块被这个使用,所以这个扇区特殊只有两个数据块。如下图,扇区的前三个块为Data Blocks(数据块),当然拥有16块的扇区数据库有15个,每个扇区的第4块(Sector Trailer(扇区尾部)控制块)包括密码A(不能读出,所以程序读出都是显示0000的)、密码B及相应扇区中的所有块的存储控制位(位于第6个字节到第9个字节)左边是低字节,则6、7、8、9字节为FF、07、80、69,这是默认的控制字,其中69是保留字节值并没有任何作用。1字节两个16进制,对应8位2进制。

 
每个扇区4块,都有三个控制区名称如下。C10,,C20,C30后面的0代表对块0的控制,前面的1,2,3代表控制区编号
块中每个控制位对应名称
 块3控制块的控制位意思如图5.1,下图中例子说明不知道为什么不是001的而是100。后直接算一遍应该是001

例子
(1)根据下表5.1和5.3:
 当C1x C2x C3x = 100时,即每个块的控制区编号都是100

(2)结合图5.2。所有C1开头的都是1,C2,C3开头的为0。_b表示取反。可得下面结果
 字节611110000
 字节7:11111111
 字节8:00000000
 字节9备用字节,随便填充如00000000


(3)然后对应的16进制为0xF0,0xFF,0x00,0x00

(4)因此此时的控制位为: (byte)0xF0, (byte)0xFF, (byte) 0x00,(byte)0x00

(5)所以根据你想要自定义对数据块和控制块数据是否可读可写。了解需求后根据图7.1和图7.3则定义好所有的C10,C20,C30,C11,C21等等等的二进制值。然后根据图7.2就得到对应二进制值了。然后转换为16进制就得到控制块的控制位的16进制值了。反之,通过控制块的控制位的16进制值得到对应二进制值,然后根据图5.2获取每个CXX的值,根据7.1和7.3图得到对应的权限
控制块中控制位意思

图7.1



图7.2


块0,1,2数据块的控制位意思
数据块的控制位

图7.3



八.M1卡通过测试结论:


 当知道密码情况下数据块可修改,控制块可修改,0扇区0块(存储id的地方)无法修改。格式化和恢复出厂也不会影响。卡买来密码是默认密码。手机可以模拟id。所以只用id判断是不够的。需要在扇区中存储id对应的加密后数据。与后台进行比较。我们平时使用时,需要把A和B密码改为我们自己的。还有我们买的卡第二控制区是FF078069(最后两字节无所谓)即密码A是无法被读取出来只能修改(不可读取情况下读出来的都是0),而密码b是可被读取和修改的,最好改为7F078869(最后两字节无所谓)。A和B都不能被读取而修改时都需要密码B。平时用authenticateSectorWithKeyA解密密码A就好。虽然如果b需要加个authenticateSectorWithKeyB就可以。

九.cardid,卡连不连接验不验证都可以读取到的。


 所以在1扇区的1块中存入。用id加密后的密文(每次加密结果都在变的)。到时与设备通过id转化的密文比较相同则id对应的科室签到成功。科室和id的关系需要存入后台。密文比较交给后台处理也可以


以上纯属个人笔记,图片和一些信息取自网上资料,如有问题请纠正!

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android调用NFC读取NFC片的过程如下:首先,需要确认设备的硬件支持NFC功能,并且设备的操作系统版本必须是Android 4.0或更高版本。然后,在Android应用程序中,需要在AndroidManifest.xml文件中添加必要的权限和NFC相关的配置。 接下来,需要在应用程序中注册一个NFC适配器对象,以便与设备的NFC芯片进行通信。然后,可以通过检测NFC设备是否处于范围内来启动应用程序的特定操作,例如读取片中的数据。 读取NFC片的过程包括以下步骤:首先,需要创建一个PendingIntent对象,以便在检测到NFC设备时接收通知。然后,使用NFC适配器对象调用enableForegroundDispatch()方法,将PendingIntent对象传递给它。这将使应用程序在检测到NFC设备时接收到通知,并初始化NFC操作。 在读取NFC片之前,需要创建一个IntentFilter对象,以过滤掉不相关的NFC标签。可以使用ACTION_NDEF_DISCOVERED和ACTION_TECH_DISCOVERED等值来设置过滤器。然后,将IntentFilter对象传递给NFC适配器的enableForegroundDispatch()方法。 当NFC适配器检测到NFC设备时,将调用应用程序的onNewIntent()方法。在onNewIntent()方法中,可以通过调用getParcelableExtra()方法获取传递给PendingIntent对象的Intent,并从中提取出NFC标签的数据。 最后,可以使用读取到的NFC标签数据进行其他的处理操作,例如解析数据、显示在应用界面上或将其发送到远程服务器等。 在读取NFC片的过程中需要注意的是,NFC设备必须处于活动状态,并且应用程序必须拥有前台调度权限,才能成功读取NFC片。此外,由于不同的NFC片类型和厂商可能有不同的协议和数据格式,因此需要根据具体的NFC片来实现相应的处理逻辑。 ### 回答2: Android调用NFC读取NFC片的过程如下: 首先,需要在AndroidManifest.xml文件中添加必要的权限和特性声明,以确保应用能够访问NFC功能。例如,需要添加以下权限声明: ``` <uses-permission android:name="android.permission.NFC" /> ``` 在应用的Activity中,需要注册一个NFC监听器,以接收NFC设备的读取事件。可以通过以下方式实现: ``` private NfcAdapter mNfcAdapter; ... @Override protected void onCreate(Bundle savedInstanceState) { ... mNfcAdapter = NfcAdapter.getDefaultAdapter(this); ... } ... @Override public void onResume() { super.onResume(); if (mNfcAdapter != null) { Intent intent = new Intent(this, this.getClass()).addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0); IntentFilter[] intentFilters = new IntentFilter[]{}; mNfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFilters, null); } } ... @Override public void onPause() { super.onPause(); if (mNfcAdapter != null) { mNfcAdapter.disableForegroundDispatch(this); } } ... @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); if (intent.hasExtra(NfcAdapter.EXTRA_TAG)) { Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // 在此处理读取到的NFC片数据 } } ``` 以上代码中,`mNfcAdapter`是NFC适配器实例,`onResume()`方法用于在应用进入前台时启用前台调度,以便接收NFC设备事件,`onPause()`方法用于在应用进入后台时禁用前台调度,`onNewIntent()`方法用于处理读取到的NFC片数据。 在`onNewIntent()`方法中,可以通过`intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)`来获取到读取到的NFC标签,并进行相应的操作,例如读取和写入片数据等。 需要注意的是,以上代码中只展示了基本的NFC读取流程,具体的读取和处理操作需要根据需求进一步实现。 ### 回答3: Android调用NFC读取NFC片需要经过以下的步骤: 首先,确保设备支持NFC功能。大多数Android设备都已经集成了NFC芯片,但仍然需要在设备的设置中确认是否启用NFC功能。 然后,在Android的Manifest文件中添加必要的权限和配置。这些权限包括NFC权限,以及与NFC相关的Intent过滤器。例如,可以添加以下代码来声明NFC权限: <uses-permission android:name="android.permission.NFC"/> 同时,还需要添加一个Intent过滤器,以便应用程序能够响应NFC相关的意图。以下是示例代码: <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED"/> </intent-filter> 接下来,需要创建一个能够响应NFC意图的活动或服务。这可以通过继承Android提供的NFC活动类或服务类来实现。在这个活动或服务中,可以使用NFC适配器来检测和连接到NFC标签。以下是示例代码: NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter != null && nfcAdapter.isEnabled()) { // NFC已经启用,可以进行相关操作 } else { // 设备不支持或未启用NFC功能 } 在检测到NFC标签后,可以通过NFC适配器获取NFC标签的ID或数据。例如,可以使用以下代码获取NFC标签的ID: Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); String tagId = bytesToHexString(tag.getId()); 最后,可以根据需要对NFC标签的ID或数据进行进一步的处理。例如,可以将ID与系统中已知的标签ID进行比较,或者读取和写入NFC标签的数据。 总之,Android调用NFC读取NFC片需要确认设备支持NFC功能、添加必要的权限和配置、创建能够响应NFC意图的活动或服务、使用NFC适配器进行NFC标签的检测和连接,并对NFC标签的ID或数据进行处理。以上是一个简单的概述,更详细的实现可以参考Android开发文档中关于NFC的相关内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值