You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用nfcpy正确模拟带有特定服务码和块数据的FeliCa NFC标签?

如何使用nfcpy正确模拟带有特定服务码和块数据的FeliCa NFC标签?

看起来你在FeliCa标签模拟上卡到了最关键的细节——我之前用nfcpy做类似项目的时候也踩过这些坑,核心问题是FeliCa的身份识别参数和服务映射必须100%匹配原卡,我来一步步帮你解决:


先解决核心问题:如何让阅读器完全识别模拟的标签

阅读器不认模拟标签的第一原因,几乎都是身份参数不匹配,然后才是服务数据的问题,按以下步骤调整:

  1. 替换硬编码的IDM/PMM/System Code为原卡的真实值
    你代码里写的idm, pmm, sys = '03FEFFE011223344', '01E0000000FFFF00', '12FC'是nfcpy的示例值,这是最大的问题!FeliCa阅读器首先会验证这三个参数,不一致直接跳过识别。
    你可以从原卡的dump结果里找到这些值(原卡dump的开头应该有类似FeliCa IDm=XXXXX, PMm=XXXXX, System Code=XXXXX的内容),把它们替换成原卡的真实十六进制值。比如你dump里的System Code是8688和FE00,先优先匹配阅读器常用的那个系统码(比如8688),测试通过后再处理多系统码的情况。

  2. 为每个捕获的服务码单独编写读写回调
    你现在用的ndef_read/ndef_write是针对标准NDEF标签的,但你的原卡是自定义服务(比如0x1A88、0x4348这些非NDEF服务),通用的NDEF回调完全不适用。正确的做法是:

    • 把每个服务的块数据单独存起来(比如用列表对应每个块的16字节内容)
    • 为每个服务写专属的read和write函数,返回对应块的捕获数据,同时遵循原卡的访问权限(比如原卡标注"write with key"的服务,write函数可以直接返回False拒绝写入,除非你实现了密钥验证逻辑)

    举个例子,针对你捕获的0x1A88服务:

    # 从原卡dump中提取0x1A88服务的块数据
    service_1A88_blocks = [
        bytearray.fromhex("30313030303030303030303000003031"),  # 块0000
        bytearray.fromhex("00000000000000000000000000000000"),  # 块0001
        bytearray.fromhex("30303030303030303230323430343031"),  # 块0002
        bytearray.fromhex("32303333303333316330303030303030"),  # 块0003
    ]
    
    def service_1A88_read(block_number, rb, re):
        # rb是请求读取的块数量,拼接对应块的字节数据返回
        response = b''
        for i in range(rb):
            target_block = block_number + i
            if target_block < len(service_1A88_blocks):
                response += service_1A88_blocks[target_block]
            else:
                response += b'\x00' * 16  # 原卡空块的默认填充值
        return response
    
    def service_1A88_write(block_number, block_data, wb, we):
        # 原卡该服务需要密钥才能写入,无密钥时拒绝操作
        return False
    

    然后在on_connect里添加这个服务:

    tag.add_service(0x1A88, service_1A88_read, service_1A88_write)
    

    用同样的方式处理其他服务(比如0x4348、0x50C8等)。

  3. 严格遵循原卡的访问权限
    你dump里的服务有"read w/o key"、"write with key"等权限,在回调函数里要对应实现:

    • 无密钥可读的服务:直接返回对应块数据
    • 需要密钥读写的服务:如果没实现密钥验证逻辑,读写函数可以返回False拒绝操作,避免阅读器报错

针对你第二个问题:nfcpy里有没有遗漏的关键点?

有几个容易忽略的细节:

  • 身份参数的完全一致性:再次强调,IDM、PMM、System Code必须和原卡完全一致,这是阅读器识别的第一关,之前的示例值必须替换。
  • 服务码的类型无需额外配置:你dump里的Random Service和Cyclic Service,nfcpy的add_service不需要额外指定类型,只要使用正确的服务码值即可。
  • 避免通用NDEF回调的误用:你的原卡不是NDEF标签,所以不要用ndef_data_area和通用的NDEF读写函数,必须为每个自定义服务写专属回调。

针对你第三个问题:有没有更好的库或方法?

如果nfcpy的FeliCa模拟确实满足不了需求(比如需要更底层的密钥处理),可以试试这些方案:

  1. libnfc + pynfc:libnfc是更底层的NFC库,pynfc是它的Python绑定,能实现更灵活的FeliCa模拟,但需要更多的底层开发(比如手动处理FeliCa的命令帧)。
  2. Sony官方FeliCa SDK:针对Sony阅读器(比如你的RC-S380)有官方的C语言SDK,能实现更完整的FeliCa功能,但需要写C代码或者用Python调用C扩展,复杂度较高。
  3. 优先调通nfcpy:其实nfcpy已经足够覆盖你的需求,只要把上面的细节调整正确,RC-S380也支持FeliCa模拟,所以优先解决当前代码的问题会更高效。

最后测试建议

调整完代码后,用你用来dump原卡的那个测试程序(就是调用tag.dump()的代码)来读取模拟的标签,对比dump结果和原卡的dump结果,确保所有服务码和块数据完全一致,这样阅读器就能识别为原卡了。

备注:内容来源于stack exchange,提问作者ちいらのちつもり

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 03:08:12