Android程式執行分析——中等複雜程度的NTAG I2C Demo為例(三)
本節接上一篇,主要討論不同認證狀態下的認證方式的具體實現
討論的內容是接這篇文章的後半部分
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晶片裡去