nfc - NTAG 424 NFC芯片的Python CRC计算

标签 nfc crc

我目前正在使用 NXP NTAG 424 chips , 具有 AES-128 加密功能。

每当设置新 key 时,该芯片都需要计算 crc32 校验值(请参阅 datasheet 11.6.1/第 67 页)。根据数据表,crc 是“根据 IEEE Std802.3-2008 计算的”。 application note (6.16.1/page 39) 甚至给出了一个例子:

new_key: F3847D627727ED3BC9C4CC050489B966
CRC32(new_key): 789DFADC

但是,当我尝试使用 python 和 binascii crc32 库复制结果时,结果不同:
>>> from binascii import unhexlify, crc32
>>> new_key = unhexlify('F3847D627727ED3BC9C4CC050489B966')
>>> print(hex(crc32(new_key)))
0x23056287     # Not the CRC I was looking for

本文档经常颠倒字节顺序,但是命令
>>> print(hex(crc32(new_key[::-1])))
0x9453faa7

也没有带来快乐。

所以问题是:我做错了什么?我尝试查阅引用的标准,但以我的肤浅知识,我无法发现标准 crc32 和 IEEE 标准中引用的算法之间有任何区别。

最佳答案

该示例的 CRC 是 补充 IEEE Std802.3(或等效的 CCITT V.42)指定的 32 位 CRC,我详细介绍了 there供引用。这是在此标签中使用标准 CRC 变体的另一种情况:与所有 ISO/IEC 14443 A 类标签一样,其错误检测(高达 848 kbit/s)使用 IEEE Std802.2 的 16 位 CRC 变体。 3(或等效CCITT V.42)规定,具有不同的初始值且缺少最终补充。

这是与问题的测试向量相匹配的自包含代码:

# compute the CRC32 for NTAG424
# Ethernet / CCITT V42 CRC32, less final complement
def NTAG424CRC(m):
    c = 0xFFFFFFFF
    for b in m:
         c ^= b;
         for n in range(8):
             c = (c>>1)^(0xEDB88320&-(c&1))
#   c ^= 0xFFFFFFFF  # required by Ethernet / CCITT V42
    return c.to_bytes(4,'little')

# demo, expected value 789dfadc
print(NTAG424CRC(bytearray.fromhex('F3847D627727ED3BC9C4CC050489B966')).hex())

Try it online!

What am I doing wrong?


  • 相信制造商忠实地执行了自己的规范。
  • 期待 binascii.crc32 的输出大端;它是小端的,在电信中必须如此,以保留 CRC32 的突发错误检测属性。这是 binascii.crc32 规范中的疏忽有一个 int作为输出,当使用 bytearray 时就像它的输入会使字节序错误几乎不可能。

  • 我们可以而且可能应该使用 binascii.crc32 ,它是原生的并使用预先计算的表,因此速度要快得多(但可能更容易受到与缓存相关的旁道攻击)。
    import binascii
    
    # compute the CRC32 for NTAG424 using binascii.crc32
    # Ethernet / CCITT V42 CRC32, less final complement
    def NTAG424CRC(m):
        return (binascii.crc32(m)&0xFFFFFFFF^0xFFFFFFFF).to_bytes(4,'little')
    # &0xFFFFFFFF deals with negative output; it can be removed under Python 3
    # ^0xFFFFFFFF undoes the complement rightly done by binascii.crc32
    
    # demo, expected value 789dfadc
    print(NTAG424CRC(bytearray.fromhex('F3847D627727ED3BC9C4CC050489B966')).hex())
    

    Try it online!

    关于nfc - NTAG 424 NFC芯片的Python CRC计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60708943/

    相关文章:

    python - Python 中的 CRC16

    java - 如何用Java计算CRC8

    android - 在 Android 委托(delegate)之前拦截 Intent (NFC)

    android - 1 个应用程序处理所有 NFC 请求,还是很多应用程序?

    nfc - 为什么有些NFC天线有两个发射器: TX1 and TX2?

    c - 反转 CRC32(a)

    c++ - C++ 中的 CRC-16 (IBM) 反向查找

    android - 如何让 Android 手机像非接触式 (NFC) 终端一样工作

    C# 读/写 Mifare NFC 标签

    java - CRC 计算花费太多时间