ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2019-11-11 09:27:10  阅读:412  来源: 互联网

标签:authentication nfc mifare android tags


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

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

更新:

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

> ultralightEV1.programPwd(passwordBytes);
> ultralightEV1.programPack(packBytes);
> ultralightEV1.enablePasswordProtection(enabled,fromPageNum);
> ultralightEV1.authenticatePwd(passwordBytes);

解决方法:

认证

ultralightEV1.authenticatePwd(passwordBytes);

为了使用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.)
    }
}

设置密码和密码确认

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

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

为了动态地发现您的标签是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;
                }
            }
        }
    }
}

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

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

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

通常,您通常会先读取(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
    });
}

标签:authentication,nfc,mifare,android,tags
来源: https://codeday.me/bug/20191111/2018876.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有