本节接上一篇,主要讨论不同认证状态下的认证方式的具体实现
讨论的内容是接这篇文章的后半部分
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芯片里去