简体   繁体   English

向 Mifare Classic 1k NFC 标签写入和读取数据

[英]Write and read data to Mifare Classic 1k NFC tag

I am trying to read and write data on a Mifare Classic 1k NFC tag.我正在尝试在 Mifare Classic 1k NFC 标签上读取和写入数据。

I found the keys and the access conditions of the card thanks to this app :由于这个应用程序,我找到了卡的钥匙和访问条件:

Keys:钥匙:

钥匙

Access Conditions:访问条件:

访问条件

<uses-permission android:name="android.permission.NFC" /> is present in my manifest. <uses-permission android:name="android.permission.NFC" />存在于我的清单中。

Here is my code:这是我的代码:

Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

if(tag != null) {
    Log.i("hey", Arrays.toString(tag.getTechList()));
    MifareClassic mfc = MifareClassic.get(tag) ;

    try {
        mfc.connect();
        boolean authA = mfc.authenticateSectorWithKeyA(2, MifareClassic.KEY_NFC_FORUM) ;
        boolean authB = mfc.authenticateSectorWithKeyB(2, MifareClassic.KEY_DEFAULT) ;
        Log.i("hey", "authA : " + authA) ;
        Log.i("hey", "authB : " + authB) ;

        if (authB && authA) {
            byte[] bWrite = new byte[16];
            byte[] hello = "hello".getBytes(StandardCharsets.US_ASCII);
            System.arraycopy(hello, 0, bWrite, 0, hello.length);
            mfc.writeBlock(0, bWrite);
            Log.i("hey", "write : " + Arrays.toString(bWrite));

            byte[] bRead = mfc.readBlock(0);
            String str = new String(bRead, StandardCharsets.US_ASCII);
            Log.i("hey", "read bytes : " + Arrays.toString(bRead));
            Log.i("hey", "read string : " + str);
            Toast.makeText(this, "read : " + str, Toast.LENGTH_SHORT).show();
            Log.i("hey", "expected : " + new String(bWrite, StandardCharsets.US_ASCII));
        }



        mfc.close();

    } catch (IOException e) {
        Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
        e.printStackTrace();
        Log.i("hey", "Error") ;
    }


}

When I try to write and read like that, what I read is not what I wrote.当我尝试这样写作和阅读时,我读到的不是我写的。

Here is the logcat:这是日志猫:

I/hey: [android.nfc.tech.NfcA, android.nfc.tech.MifareClassic, android.nfc.tech.NdefFormatable]
I/hey: authA : true
    authB : true
I/hey: write : [104, 101, 108, 108, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
I/hey: read byte : [-78, 0, 0, 0, 0, 0, -1, 7, -128, 105, -1, -1, -1, -1, -1, -1]
    read string : �������������i������
I/hey: expected : hello����������������������

I tried with different charsets but it didn't change anything.我尝试了不同的字符集,但它没有改变任何东西。

I also tried to only read the Sector 0 by commenting the write part and changing authentication key A to MifareClassic.KEY_MIFARE_APPLICATION_DIRECTORY and this time I get this Logcat:我还尝试通过评论写入部分并将身份验证密钥 A 更改为MifareClassic.KEY_MIFARE_APPLICATION_DIRECTORY来仅读取扇区 0,这次我得到了这个 Logcat:

I/hey: [android.nfc.tech.NfcA, android.nfc.tech.MifareClassic, android.nfc.tech.NdefFormatable] 
I/hey: authA : true
        authB : true 
I/hey: read bytes : [-123, -121, 0, 16, 18, 8, 4, 0, 1, -64, 62, -70, 74, 124, 78, 29]
        read string : �������>�J|N

Any idea about how can I fix it to write and display text properly?关于如何修复它以正确编写和显示文本的任何想法?

You first authenticate to sector 2:您首先对扇区 2 进行身份验证:

boolean authA = mfc.authenticateSectorWithKeyA(2, MifareClassic.KEY_NFC_FORUM);
boolean authB = mfc.authenticateSectorWithKeyB(2, MifareClassic.KEY_DEFAULT);

Then, you try to write and read block 0:然后,您尝试写入和读取块 0:

mfc.writeBlock(0, bWrite);
byte[] bRead = mfc.readBlock(0);

There are several problems with this:这有几个问题:

  1. It does not make sense to authenticate using both key A and key B. Only the last authentication determines the authentication state of the tag.使用密钥 A 和密钥 B 进行身份验证是没有意义的。只有最后一次身份验证才能确定标签的身份验证状态。 Since all sectors seem to be writable using key B, you can safely use the second line ( mfc.authenticateSectorWithKeyB() only).由于所有扇区似乎都可以使用密钥 B 写入,因此您可以安全地使用第二行( mfc.authenticateSectorWithKeyB() )。

  2. You authenticate to sector 2, which consists of blocks 8, 9, 10, and 11. Writing and reading block 0 does not make sense in that authentication state.您对扇区 2 进行身份验证,该扇区由块 8、9、10 和 11 组成。在该身份验证状态下写入和读取块 0 没有意义。 Note that read/write operations typically use global block numbering.请注意,读/写操作通常使用全局块编号。 Sectors are only used as logical units for authentication/access control purposes.扇区仅用作用于身份验证/访问控制目的的逻辑单元。 You can easily calculate block numbers from sector numbering using mfc.sectorToBlock() and mfc.getBlockCountInSector() .您可以使用mfc.sectorToBlock()mfc.getBlockCountInSector()从扇区编号轻松计算块编号。

  3. Block 0 (in sector 0) is a special block, the manufacturer block.块 0(在扇区 0 中)是一个特殊块,即制造商块。 It typically contains the UID, SAK and manufacturer information burned into the tag during the production process.它通常包含在生产过程中烧入标签的 UID、SAK 和制造商信息。 This block is read-only and cannot be changed.此块是只读的,不能更改。 Consequently, writing to that block does not have any effect.因此,写入该块没有任何效果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM