如何在MIFARE Ultralight EV1标签上设置和取消设置密码? [英] How to set and unset password on a MIFARE Ultralight EV1 tag?

查看:81
本文介绍了如何在MIFARE Ultralight EV1标签上设置和取消设置密码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够使用Android上的 NfcA?标签技术在MIFARE Ultralight EV1(MFOUL21)标签上设置和取消密码保护.

I would like to be able to set and unset password protection on a MIFARE Ultralight EV1 (MFOUL21) tag using the NfcA? tag technology on Android.

我知道我会为此使用 nfcA.transceive()方法,但是我不确定该方法的参数是什么,因此任何人都可以提供设置和取消设置的代码段密码?

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?

更新:

关于TapLinx库,我基本上希望 nfcA.transceive(...)代码段等效于:

With respect to the TapLinx library, I would basically like the nfcA.transceive(...) code snippets equvalent to:

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

推荐答案

验证

ultralightEV1.authenticatePwd(passwordBytes);

ultralightEV1.authenticatePwd(passwordBytes);

为了使用MIFARE Ultralight EV1标签(或NTAG21x)的密码进行身份验证,您需要发送PWD_AUTH(0x1B)命令(并可能验证PACK响应是否符合您的期望):

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):

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.)
    }
}

设置密码和密码确认

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

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

对于MF0UL11,密码位于第0x12页,密码确认(PACK)位于第0x13页(配置页从0x10开始).对于MF0UL21,密码位于第0x27页,密码确认(PACK)位于第0x28页(配置页从0x25开始).

For MF0UL11, the password is on page 0x12 and the password-acknowledge (PACK) is on page 0x13 (configuration pages start at 0x10). For MF0UL21, the password is on page 0x27 and the password-acknowledge (PACK) is on page 0x28 (configuration pages start at 0x25).

为了动态地找出您的标签是MF0UL11还是MF0UL21,您可以发送GET_VERSION(0x60)命令:

In order to dynamically find out if your tag is MF0UL11 or MF0UL21, you could send a GET_VERSION (0x60) command:

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;
                }
            }
        }
    }
}

找到配置页面的开头后,可以使用WRITE(0xA2)命令更新这些页面的值(假设您已使用当前密码进行了身份验证,或者配置页面未受保护):

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):

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)
});

启用密码保护

ultralightEV1.enablePasswordProtection(enabled,fromPageNum);

ultralightEV1.enablePasswordProtection(enabled, fromPageNum);

要启用密码保护,您需要配置需要密码的第一页(AUTH0,MF0UL11/0x25 MF0UL21第0x10页的字节3),并且需要配置保护模式(PROT,第7位,第7位).MF0UL11/页0x26 MF0UL21在0x11页上的字节0).

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).

通常,您通常会先读取(READ(0x30)命令)这些页面的旧值,更新受影响的位和字节,然后将新值写入标记:

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:

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
    });
}

这篇关于如何在MIFARE Ultralight EV1标签上设置和取消设置密码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆