Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(三)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_24118527/article/details/82950796

本节接上一篇,主要讨论不同认证状态下的认证方式的具体实现

讨论的内容是接这篇文章的后半部分

https://blog.csdn.net/qq_24118527/article/details/82950545


protectPlus

首先看第一个

这个函数的实现如下

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.nxp.nfc_demo.reader.I2C_Enabled_Commands#protectPlus()
	 * 
	 */
	//See P23
	@Override
	public void protectPlus(byte[] pwd, byte startAddr) throws IOException,
			FormatException, NotPlusTagException {
		byte[] data = new byte[4];
		
		if(getProduct() != Prod.NTAG_I2C_1k_Plus && getProduct() != Prod.NTAG_I2C_2k_Plus) {
			throw new NotPlusTagException(
					"Auth Operations are not supported by non NTAG I2C PLUS products");
		}
		reader.SectorSelect((byte) 0);
		
		// Set the password indicated by the user
		reader.write(pwd, Register.PWD.getValue());

		//See P24
		//Access Conditions----------------------------------------------------------
		byte access = (byte) 0x00;
		byte authLimit = 0x00; 				// Don't limit the number of auth attempts


		access ^= 1 << Access_Offset.NFC_PROT.getValue();			// NFC_Prot
		access ^= 0 << Access_Offset.NFC_DIS_SEC1.getValue();		// NFC_DIS_SEC1
		access |= authLimit << Access_Offset.AUTH_LIM.getValue();	// AUTHLIM
		
		// Write the ACCESS configuration
		data[0] = access;
		data[1] = 0x00;
		data[2] = 0x00;
		data[3] = 0x00;
		reader.write(data, Register.ACCESS.getValue());
		//Access Conditions End-------------------------------------------------------

		//See P24
		//Protection bits (PT_I2C)------------------------------------------------------
		byte ptI2C = 0x00;
		byte i2CProt = 0x00;

		ptI2C ^= 0 << PT_I2C_Offset.K2_PROT.getValue();			// 2K Prot
		ptI2C ^= 1 << PT_I2C_Offset.SRAM_PROT.getValue();			// SRAM Prot
		ptI2C |= i2CProt << PT_I2C_Offset.I2C_PROT.getValue();	// I2C Prot

		// Write the PT_I2C configuration-----------------------------------------------
		data[0] = ptI2C;
		data[1] = 0x00;
		data[2] = 0x00;
		data[3] = 0x00;
		reader.write(data, Register.PT_I2C.getValue());
		//Protection bits (PT_I2C) End--------------------------------------------------

		// See P12
		// AUTH0-------------------------------------------------------------------
		// Write the AUTH0 lock starting page
		data[0] = 0x00;
		data[1] = 0x00;
		data[2] = 0x00;
		data[3] = startAddr;
		reader.write(data, Register.AUTH0.getValue());
		// AUTH0 End----------------------------------------------------------------
	}

可以看到这个函数的实现是很复杂的,用到了一些位操作,分析如下:

首先new一个4byte的数组

显然这个就是拿来放pwd的,因为pwd就是4个byte的

紧接着我调用getProduct()函数,并且判断其返回值,这个函数的具体实现以后有机会再细说,可以简单地理解为,NXP NFC芯片的某些寄存器里存放了这款芯片的产品型号信息,通过这个函数可以读取这些寄存器,从而获得当前这款芯片的产品信息

紧接着选择sector0,这里用到的SectorSelect函数具体实现以后有机会再说,可以简单地理解为,选择接下来要操作sector

然后,进行使用write函数,这个函数有2个参数,一个是你选择的pwd(或者说你输入的pwd),另外一个是NXP NFC芯片中pwd保存的offset,其实就是常数0xE5

需要注意的一点是,在这种状态下,上一个图片中的这句话实际上是在做一个输入密码的操作,而不能说是一个认证操作(说是认证容易引起歧义)

下面是对access寄存器的一些操作,操作的方法很简单,你新建一个byte,名为access,初始化为0x00,然后对这个access进行修改,之后再把这个access写入到NXP NFC芯片中

我们看一下实现的代码,先初始化两个byte

下面3句代码,前2句是模2加(异或),最后一句是按位或


因为每次传输都是传4个byte,因此接下来的传输操作如图所示

类似地,接下来进行对PT_I2C寄存器的配置,配置的方法很简单,和上面都是一样的

类似地,接下来对AUTH0寄存器进行配置

至此,protectPlus完成


unprotectPlus

/*
	 * (non-Javadoc)
	 * 
	 * @see com.nxp.nfc_demo.reader.I2C_Enabled_Commands#unprotectPlus()
	 * 
	 */
	@Override
	public void unprotectPlus() throws IOException, FormatException, NotPlusTagException {
		byte[] data = new byte[4];
		
		if(getProduct() != Prod.NTAG_I2C_1k_Plus && getProduct() != Prod.NTAG_I2C_2k_Plus) {
			throw new NotPlusTagException(
					"Auth Operations are not supported by non NTAG I2C PLUS products");
		}
		reader.SectorSelect((byte) 0);

		// See P24
		// AUTH0-------------------------------------------------------------------
		// Write the AUTH0 lock starting page
		data[0] = 0x00;
		data[1] = 0x00;
		data[2] = 0x00;
		data[3] = (byte) 0xFF;
		reader.write(data, Register.AUTH0.getValue());
		// AUTH0 End----------------------------------------------------------------

		// P24
		// PWD---------------------------------------------------------------------
		// Set the password to FFs
		data[0] = (byte) 0xFF;
		data[1] = (byte) 0xFF;
		data[2] = (byte) 0xFF;
		data[3] = (byte) 0xFF;
		reader.write(data, Register.PWD.getValue());
		// PWD End------------------------------------------------------------------

		// SeeP24
		// ACCESS-------------------------------------------------------------------
		// Write the ACCESS configuration
		data[0] = 0x00;
		data[1] = 0x00;
		data[2] = 0x00;
		data[3] = 0x00;
		reader.write(data, Register.ACCESS.getValue());
		// ACCESS End---------------------------------------------------------------

		// Write the PT_I2C configuration------------------------------------------------
		// Write the PT I2C configuration
		data[0] = 0x00;
		data[1] = 0x00;
		data[2] = 0x00;
		data[3] = 0x00;
		reader.write(data, Register.PT_I2C.getValue());
		// Write the PT_I2C configuration End--------------------------------------------
	}

稍微看一下这个函数的实现,你会发现,和上一个函数非常相似,但是少去了你设置初始密码的环节

一样的套路

配置Auth0寄存器

配置Access寄存器

配置PT_I2C寄存器

至此这个函数也结束了


authenticatePlus

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.nxp.nfc_demo.reader.I2C_Enabled_Commands#authenticatePlus()
	 * 
	 */
	@Override
	public byte[] authenticatePlus(byte[] pwd) throws IOException, NotPlusTagException {
		if(getProduct() != Prod.NTAG_I2C_1k_Plus && getProduct() != Prod.NTAG_I2C_2k_Plus) {
			throw new NotPlusTagException(
					"Auth Operations are not supported by non NTAG I2C PLUS products");
		}
		return reader.pwdAuth(pwd);
	}

可以看到,前面的套路是一样的,但是后面调用了pwdAuth函数

这个函数的实现是这样的,说白了就是把你的密码传到NXP NFC芯片里去

猜你喜欢

转载自blog.csdn.net/qq_24118527/article/details/82950796