简体   繁体   English

如何在MIFARE Ultralight EV1标签上设置和取消设置密码?

[英]How to set and unset password on a MIFARE Ultralight EV1 tag?

I would like to be able to set and unset password protection on a MIFARE Ultralight EV1 (MFOUL21) tag using the NfcA? 我希望能够使用NfcA?在MIFARE Ultralight EV1(MFOUL21)标签上设置和取消密码保护NfcA? tag technology on Android. Android上的标记技术。

I understand I would use the nfcA.transceive() method for this, but I'm not sure what the arguments to that method would be, so could anyone provide code snippets to set and unset the password? 我知道我会使用nfcA.transceive()方法,但我不确定该方法的参数是什么,所以任何人都可以提供代码片段来设置和取消设置密码吗?

Update: 更新:

With respect to the TapLinx library, I would basically like the nfcA.transceive(...) code snippets equvalent to: 关于TapLinx库,我基本上喜欢nfcA.transceive(...)代码片段等价于:

  1. ultralightEV1.programPwd(passwordBytes);
  2. ultralightEV1.programPack(packBytes);
  3. ultralightEV1.enablePasswordProtection(enabled, fromPageNum);
  4. ultralightEV1.authenticatePwd(passwordBytes);

Authenticate 认证

ultralightEV1.authenticatePwd(passwordBytes); ultralightEV1.authenticatePwd(passwordBytes);

In order to authenticate with the password to a MIFARE Ultralight EV1 tag (or NTAG21x), you would need to send the PWD_AUTH (0x1B) command (and possibly verify if the PACK response matches your expectations): 要使用MIFARE Ultralight EV1标签(或NTAG21x)的密码进行身份验证,您需要发送PWD_AUTH(0x1B)命令(并可能验证PACK响应是否符合您的预期):

byte[] pass = { (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78 };
byte[] pack = { (byte)0x9A, (byte)0xBC };

byte[] response = nfc.transceive(new byte[] {
    (byte) 0x1B, // PWD_AUTH
    pass[0], pass[1], pass[2], pass[3]
});
if ((response != null) && (response.length >= 2)) {
    // success
    byte[] packReceived = Arrays.copyOf(response, 2);
    if (Arrays.equal(packReceived, pack)) {
        // PACK verified, so tag is authentic (not really, but that whole
        // PWD_AUTH/PACK authentication mechanism was not really meant to
        // bring much security, I hope; same with the NTAG signature btw.)
    }
}

Set password and password-acknowledge 设置密码和密码确认

ultralightEV1.programPwd(passwordBytes); ultralightEV1.programPwd(passwordBytes); ultralightEV1.programPack(packBytes); ultralightEV1.programPack(packBytes);

For MF0UL11, the password is on page 0x12 and the password-acknowledge (PACK) is on page 0x13 (configuration pages start at 0x10). 对于MF0UL11,密码位于第0x12页,密码确认(PACK)位于第0x13页(配置页面从0x10开始)。 For MF0UL21, the password is on page 0x27 and the password-acknowledge (PACK) is on page 0x28 (configuration pages start at 0x25). 对于MF0UL21,密码位于第0x27页,密码确认(PACK)位于第0x28页(配置页面从0x25开始)。

In order to dynamically find out if your tag is MF0UL11 or MF0UL21, you could send a GET_VERSION (0x60) command: 为了动态地找出您的标签是MF0UL11还是MF0UL21,您可以发送GET_VERSION(0x60)命令:

int cfgOffset = -1;

byte[] response = nfc.transceive(new byte[] {
    (byte) 0x60 // GET_VERSION
});
if ((response != null) && (response.length >= 8)) {
    // success
    if ((response[0] == (byte)0x00) && (response[1] == (byte)0x04)) {
        // tag is from NXP
        if (response[2] == (byte)0x03) {
            // MIFARE Ultralight
            if ((response[4] == (byte)0x01) && (response[5] == (byte)0x00) {
                // MIFARE Ultralight EV1 (V0)
                switch (response[6]) {
                    case (byte)0x0B:
                        // MF0UL11
                        cfgOffset = 0x010;
                        break;
                    case (byte)0x0E:
                        // MF0UL11
                        cfgOffset = 0x025;
                        break;

                    default:
                        // unknown
                        break;
                }
            }
        }
    }
}

Once you found the begin of the configuration pages, you can use a WRITE (0xA2) command to update the values of those pages (assuming you are authenticated with the current password otr the configuration pages are unprotected): 找到配置页面的开头后,可以使用WRITE(0xA2)命令更新这些页面的值(假设您使用当前密码进行身份验证otr,配置页面不受保护):

byte[] response = nfc.transceive(new byte[] {
    (byte) 0xA2, // WRITE
    (byte)((cfgOffset + 2) & 0x0FF),    // page address
    pass[0], pass[1], pass[2], pass[3]  // new page data
});
response = nfc.transceive(new byte[] {
    (byte) 0xA2, // WRITE
    (byte)((cfgOffset + 3) & 0x0FF),          // page address
    pack[0], pack[1], (byte)0x00, (byte)0x00  // new page data (always need to write full page)
});

Enable password protection 启用密码保护

ultralightEV1.enablePasswordProtection(enabled, fromPageNum); ultralightEV1.enablePasswordProtection(启用,fromPageNum);

In order to enable password protection, you need to cofigure the first page that requires the password (AUTH0, byte 3 on page 0x10 for MF0UL11/page 0x25 MF0UL21) and you need to configure the protection mode (PROT, bit 7 of byte 0 on page 0x11 for MF0UL11/page 0x26 MF0UL21). 为了启用密码保护,您需要配置需要密码的第一页(AUTH0,第1,010页上的字节3(对于MF0UL11 /第0x25页MF0UL21),您需要配置保护模式(PROT,字节0的第7位) MF0UL11 /页0x26 MF0UL21)的第0x11页。

You would typically first read (READ (0x30) command) the old value of those pages, update the affected bits and bytes, and write the new value to the tag: 您通常首先读取(READ(0x30)命令)这些页面的旧值,更新受影响的位和字节,并将新值写入标记:

int fromPageNum = 4;
boolean enableProtection = true;
boolean enableReadProtection = true;
byte[] response = nfc.transceive(new byte[] {
    (byte) 0x30, // READ
    (byte)(cfgOffset & 0x0FF)  // page address
});
if ((response != null) && (response.length >= 16)) {
    // success
    // NOTE that READ will return *4 pages* starting at page address
    byte auth0 = (byte)0xFF;
    if (enableProtection || enableReadProtection) {
        auth0 = (byte)(fromPageNum & 0x0FF);
    }
    byte[] writeResponse = nfc.transceive(new byte[] {
        (byte) 0xA2, // WRITE
        (byte)((cfgOffset + 0) & 0x0FF),              // page address
        response[0], response[1], response[2], auth0  // new page data
    });
    byte access = (byte)(response[4] & 0x07F);
    if (enableProtection && enableReadProtection) {
        access |= (byte)0x80;
    }
    byte[] writeResponse = nfc.transceive(new byte[] {
        (byte) 0xA2, // WRITE
        (byte)((cfgOffset + 1) & 0x0FF),                // page address
        access, response[5], response[6], response[7],  // new page data
    });
}

You can use the TapLinx Library from NXP (available at https://www.mifare.net/en/products/tools/taplinx/ ) to communicate with MIFARE Ultralight EV1 in an abstracted manner. 您可以使用恩智浦的TapLinx库(可从https://www.mifare.net/en/products/tools/taplinx/获得 )以抽象的方式与MIFARE Ultralight EV1进行通信。

To use "transceive", according to the datasheet available at http://www.advanide.com/wp-content/uploads/products/rfid/UltraLight%20EV1_MF0ULX1.pdf the WRITE Command (A2) needs to be used, with addresses 25-28h. 要使用“收发”,根据http://www.advanide.com/wp-content/uploads/products/rfid/UltraLight%20EV1_MF0ULX1.pdf上提供的数据表,需要使用WRITE命令(A2)和地址25-28h。

UPDATE: The commands to be sent should be (for MFOUL21): 更新:要发送的命令应该是(对于MFOUL21):

  1. ultralightEV1.programPwd(passwordBytes); ultralightEV1.programPwd(passwordBytes); A227AABBCCDD (for Password AABBCCDD) A227AABBCCDD(密码AABBCCDD)

  2. ultralightEV1.programPack(packBytes); ultralightEV1.programPack(packBytes); A228EEFF0000 (for PACK 0000) A228EEFF0000(适用于PACK 0000)

  3. ultralightEV1.enablePasswordProtection(enabled, fromPageNum); ultralightEV1.enablePasswordProtection(启用,fromPageNum); A225xx0000yy (where xx is the modulation mode; 00..strong mod. disabled; 01..strong mod enabled; yy = page where password protection starts) A225xx0000yy(其中xx是调制模式; 00..strong mod。禁用; 01..strong mod启用; yy =密码保护开始的页面)

  4. ultralightEV1.authenticatePwd(passwordBytes); ultralightEV1.authenticatePwd(passwordBytes); 1BAABBCCDD 1BAABBCCDD

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

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