【问题标题】:Is it possible to read the iPhone's NFC chip as if it were an RFID tag?是否可以像读取 RFID 标签一样读取 iPhone 的 NFC 芯片?
【发布时间】:2015-08-04 00:10:47
【问题描述】:

我知道 iPhone 6 无法读取 RFID 标签,并且我知道 iPhone API 只允许将 NFC 用于 Apple Pay,但是否可以像读取 RFID 标签一样读取 iPhone 的 NFC 芯片?

也就是说,RFID 阅读器是否能够通过将 RFID 阅读器与 Arduino 或 Raspberry Pi 之类的东西结合使用来检索任何类型的被动信息,例如芯片的唯一 ID 或类似性质的东西?

【问题讨论】:

    标签: iphone arduino raspberry-pi nfc rfid


    【解决方案1】:

    正如Michael Gillett 已经写的那样,防冲突标识符(经常用作 RFID 中的 ID)是动态的,并且在每次激活安全时都会发生变化iPhone 中的元素。您可以尝试做的是访问安全元件上的 EMV 支付卡(“标记化”信用卡)。该信用卡至少包含一个 PAN(令牌化主帐号),可能还包含用于签名验证的公钥。该信息应该是静态的(即使在标记化的情况下),因此可用于识别设备。

    查看非接触式支付系统 (http://emvco.com) 的 EMV 规范,了解如何访问支付应用程序。基本上你会做如下的事情:

    • 选择 PPSE
    • 在选择响应中查找支付应用程序的 AID
    • 选择付款申请(通过 AID)
    • 为包含 PAN/ICC 公钥的记录读取记录(文件 + 记录号)

    不过,您需要一些非接触式智能卡读卡器来发送必要的 APDU 命令。仅执行防冲突以获取 ID 的 RFID 阅读器是不够的。然而,对于 Arduino 和 RPI,都有这样的阅读器(例如 NFC shield)。

    【讨论】:

      【解决方案2】:

      当您按住拇指尝试 Apple Pay 付款时,似乎可以检测到来自 iPhone 的信号。但是,它会在每次按下时发出不同的 ID 号。这使得几乎不可能做任何与安​​全相关的事情。

      这是一个有人让它工作的视频。 https://www.youtube.com/watch?v=fhpMVFte2mE

      因为 iPhone 每次都会吐出不同的 NFC 标签#。阅读器设置为使用任何标签,这不利于安全应用,如上面视频中的锁。

      【讨论】:

      • 见鬼,看完那个 youtube 剪辑后,我不知何故花了半个小时看着人们毁坏新的 iPhone……同样的头脑麻木的原因我不看电视。
      • 真可惜。希望 Apple 最终会开放 API(就像他们对许多以前受限的 API 所做的那样),以便将其用于其他目的!
      • 我觉得他们肯定会在某个时候开放它,尤其是最近推动家庭自动化与家庭套件。它将成为锁的完美钥匙。
      • @MichaelGillett 这实际上正是我想要使用它的目的!解锁我的前门!我想我最终可能会使用蓝牙和安装在门上的小键盘进行双重身份验证。
      【解决方案3】:

      使用 PN532 板。使用基于 Arduino 的主机简化工作,使用 this library

      定义连接。

      #include <Arduino.h>
      #include <SPI.h>
      #include <PN532_SPI.h>
      #include <PN532.h>
      
      PN532_SPI intfc(SPI,5);
      PN532 nfc(intfc);
      

      检查卡/手机是否存在:

      success = nfc.inListPassiveTarget();
         if (success) { ...
      

      定义通讯缓冲区:

         uint8_t apdubuffer[255] = {};
         uint8_t apdulen;
      

      并发送 SELECT PPSE 命令:

      apdulen = 255;
      success2 = sendAPDU(0x00, 0xA4, 0x04, 0x00, "2PAY.SYS.DDF01", 0x00, &apdubuffer[0], &apdulen);
      

      如果成功,则:

      //fromHEX("A0000000031010") - VISA
      //fromHEX("A0000000041010") - MC
      success2 = sendAPDU(0x00, 0xA4, 0x04, 0x00, fromHEX("A0000000031010"), 0x00, &apdubuffer[0], &apdulen);
      

      并且您可以很好地阅读卡的内部文件 (SFI/REC),例如:

      success2 = sendAPDU(0x00, 0xB2, rec_num, (sfi_num << 3)+4, 0x00, &apdubuffer[0], &apdulen);
      

      最好找到 PAN/ICC 公钥,确实,对卡来说是唯一的,但是在 PAN/ICC 之前会有很多字节,恕我直言,非常独特,足以执行身份验证

      毕竟,你需要这个重载:

      bool sendAPDU(byte cla, byte ins, byte p1, byte p2, String aid, byte le, uint8_t *response, uint8_t *resp_len)
      {
        uint8_t cmdbuf[255];
        memset(&cmdbuf[0],0,255);
        cmdbuf[0] = cla;
        cmdbuf[1] = ins;
        cmdbuf[2] = p1;
        cmdbuf[3] = p2;
        cmdbuf[4] = aid.length();  
        int i;
        for (i=0;i<aid.length();i++)
          cmdbuf[5+i] = aid[i];
        cmdbuf[6+i] = le;
        //printbuf((char*)&cmdbuf[0],5+aid.length());
        return nfc.inDataExchange(&cmdbuf[0], 5+aid.length(), response, resp_len);
      }
      
      bool sendAPDU(byte cla, byte ins, byte p1, byte p2, uint8_t* aid, byte le, uint8_t *response, uint8_t *resp_len)
      {
        uint8_t cmdbuf[255];
        memset(&cmdbuf[0],0,255);
        cmdbuf[0] = cla;
        cmdbuf[1] = ins;
        cmdbuf[2] = p1;
        cmdbuf[3] = p2;
        cmdbuf[4] = aid[0];  
        int i;
        for (i=0;i<aid[0];i++)
          cmdbuf[5+i] = aid[i+1];
        cmdbuf[6+i] = le;
        //printbuf((char*)&cmdbuf[0],5+cmdbuf[4]);
        return nfc.inDataExchange(&cmdbuf[0], 5+cmdbuf[4], response, resp_len);
      }
      
      bool sendAPDU(byte cla, byte ins, byte p1, byte p2, byte le, uint8_t *response, uint8_t *resp_len)
      {
        uint8_t cmdbuf[255];
        memset(&cmdbuf[0],0,255);
        cmdbuf[0] = cla;
        cmdbuf[1] = ins;
        cmdbuf[2] = p1;
        cmdbuf[3] = p2;
        cmdbuf[4] = le;
        //printbuf((char*)&cmdbuf[0],5);
        return nfc.inDataExchange(&cmdbuf[0], 5, response, resp_len);
      }
      
      

      还有这个:

      /*
        Funny, non-C approach to return array from a function
        Returns ptr to global static buf... 
        Just to improve readability of sendAPDU() function...
        Not really needed in real app,
      */
      uint8_t fromHexBuf[255];  
      uint8_t* fromHEX(String hexs) {
        int i = hexs.length()/2;
        fromHexBuf[0] = i;
        int x=0;
        while (i) {
          char buf[3];
          char *tmp;
          buf[0] = hexs[2*x];
          buf[1] = hexs[2*x+1];
          buf[2] = 0;    
          uint8_t v = strtol(&buf[0], &tmp, 16);
          //Serial.printf("-> %s = %x\n", buf, v);
          fromHexBuf[x+1] = v;
          x=x+1;
          i--;
        }
        return &fromHexBuf[0];
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-25
        • 1970-01-01
        • 1970-01-01
        • 2016-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多