我正在使用 Xamarin.Forms 和 Plugin.NFC 库开发 NFC 测试应用程序: https://github.com/franckbour/Plugin.NFC/
但是,该库不包含设置或删除密码的功能,因此我需要自己添加该功能。
我在这里添加卡信息。
My card is ISO 14443-3A
NXP - NTAG213
NfcA, MifareUltralight, Ndef
and below there is exported memory
这是内存转储
[ 04:C1:FE:B3 ] Addr. 00 : UID0 - UID2 / BCC0
[ F2:04:74:80 ] Addr. 01 : UID3 - UDI6
[ 02:48:00:00 ] Addr. 02 : BCC1 / INT. / LOCK0 - LOCK1
[ E1:10:12:00 ] Addr. 03 : OTP0 - OTP3
[ 01:03:A0:0C ] Addr. 04 : DATA
[ 34:03:0A:D1 ] Addr. 05 : DATA
[ 01:06:54:02 ] Addr. 06 : DATA
[ 65:6E:61:61 ] Addr. 07 : DATA
[ 61:FE:00:00 ] Addr. 08 : DATA
[ 63:3F:54:61 ] Addr. 09 : DATA
[ 67:49:64:3D ] Addr. 0A : DATA
[ 30:34:43:31 ] Addr. 0B : DATA
[ 46:45:46:32 ] Addr. 0C : DATA
[ 30:34:37:34 ] Addr. 0D : DATA
[ 38:30:26:50 ] Addr. 0E : DATA
[ 61:79:6C:6F ] Addr. 0F : DATA
[ 61:64:3D:4D ] Addr. 10 : DATA
[ 79:5F:49:6D ] Addr. 11 : DATA
[ 70:6F:72:74 ] Addr. 12 : DATA
[ 61:6E:74:5F ] Addr. 13 : DATA
[ 4B:65:79:FE ] Addr. 14 : DATA
[ 73:20:65:76 ] Addr. 15 : DATA
[ 65:72:79:74 ] Addr. 16 : DATA
[ 68:69:6E:67 ] Addr. 17 : DATA
[ 20:6F:6B:3F ] Addr. 18 : DATA
[ 20:79:65:73 ] Addr. 19 : DATA
[ 20:69:74:20 ] Addr. 1A : DATA
[ 69:73:FE:00 ] Addr. 1B : DATA
[ 70:73:75:6D ] Addr. 1C : DATA
[ 20:68:61:73 ] Addr. 1D : DATA
[ 20:62:65:65 ] Addr. 1E : DATA
[ 6E:20:74:68 ] Addr. 1F : DATA
[ 65:20:69:6E ] Addr. 20 : DATA
[ 64:75:73:74 ] Addr. 21 : DATA
[ 72:79:27:73 ] Addr. 22 : DATA
[ 20:73:74:61 ] Addr. 23 : DATA
[ 6E:64:61:72 ] Addr. 24 : DATA
[ 64:20:64:75 ] Addr. 25 : DATA
[ 6D:6D:79:FE ] Addr. 26 : DATA
[ 00:00:00:00 ] Addr. 27 : DATA
[ 00:00:00:BD ] Addr. 28 : LOCK2 - LOCK4
[ 04:00:00:00 ] Addr. 29 : CFG 0 (MIRROR / AUTH0)
[ 00:05:00:00 ] Addr. 2A : CFG 1 (ACCESS)
[ 00:00:00:00 ] Addr. 2B : PWD0 - PWD3
[ 00:00:00:00 ] Addr. 2C : PACK0 - PACK1
我可以在Android中使用以下代码来检测卡是否受密码保护。
public bool CheckConfiguration()
{
bool passExist;
MifareUltralight mu = null;
try
{
mu = MifareUltralight.Get( _currentTag );
mu.Connect();
var answer = mu.ReadPages( 41 );
byte auth0 = answer[ 3 ];
passExist = auth0 < (byte)0xEB;
Debug.WriteLine( "Page 41 (addr29)" );
Debug.WriteLine( string.Join( "", answer ) );
mu.Close();
}
catch( Exception e )
{
mu?.Close();
passExist = true;
}
return passExist;
}
认证状态位于地址0x29。如果最后一个字节是0x00,则表示该卡受密码保护;如果最后一个字节是0xFF,则表示该卡没有密码保护。
我能够发送基本命令并成功接收结果。
private void TestReadBlock(MifareUltralight mfu)
{
try
{
if (!mfu.IsConnected)
mfu.Connect();
// Read block 4 as a test
byte[] readCommand = { 0x30, 0x04 }; // Read block 4
byte[] response = mfu.Transceive(readCommand);
if (response != null)
{
Debug.WriteLine($"Read successful. Response: {BitConverter.ToString(response)}");
}
else
{
Debug.WriteLine("Read failed. Response is null.");
}
}
catch (Java.IO.IOException ex)
{
Debug.WriteLine($"IOException during read: {ex.Message}");
}
finally
{
try
{
if (mfu.IsConnected)
mfu.Close();
}
catch (Exception ex)
{
Debug.WriteLine($"Failed to close connection: {ex.Message}");
}
}
}
我可以获得结果。
但是,当我尝试使用 0x1B 命令进行身份验证时,我总是收到错误“标签丢失。”
例如,我第一次调用Transceive方法时出现异常。
private bool RemovePasswordProtection(MifareUltralight mfu)
{
try
{
if (!mfu.IsConnected)
mfu.Connect();
byte[] pwdAuthCommand = { 0x1B, 0x00, 0x00, 0x00, 0x00 };
byte[] response = mfu.Transceive(pwdAuthCommand);
byte[] writeCommand = { 0xA2, 0x29, 0xFF, 0x00, 0x00, 0x00 };
mfu.Transceive(writeCommand);
return true;
}
catch (Exception ex)
{
Debug.WriteLine($"Error removing password protection: {ex.Message}");
return false;
}
finally
{
try
{
if (mfu.IsConnected)
mfu.Close();
}
catch { }
}
}
我不确定命令是否不正确或者是否存在其他潜在问题。需要注意的一件事是,我在检测到标签后调用此身份验证方法。
很可能
{ 0x00, 0x00, 0x00, 0x00 }
不是密码。
根据数据表第8.8.1节
PWD 和 PACK 字节永远无法从内存中读出。而不是传输 任何有效 READ 或 FAST_READ 命令的实际值,仅回复 00h 字节。
您需要知道真实密码,您无法从转储中读取密码。
如果您尝试使用错误的密码进行身份验证,标签将进入 HALT 状态,从而出现标签丢失错误。