Android程式執行分析——中等複雜程度的NTAG I2C Demo為例(二)
阿新 • • 發佈:2018-12-13
本節主要討論NTAG I2C Demo這個APP裡的認證機制(安全機制)
文中會結合一些NXP NFC晶片DataSheet中的內容,但會以儘可能簡單的語言描述
首先看一下這句程式碼
mAuthStatus是一個int型的變數,以private static修飾,足見其安全程度之高
這個變數的初始化是在這個地方,當然一開始初始化為Disabled ,也就是預設你是沒有許可權的
接下來看一下launchDemo的實現
private void launchDemo(String currTab) { if(mAuthStatus == AuthStatus.Authenticated.getValue()) { demo.Auth(mPassword, AuthStatus.Protected_RW.getValue()); } // =========================================================================== // LED Test // =========================================================================== if (currTab.equalsIgnoreCase("leds")) { // This demo is available even if the product is protected // as long as the SRAM is unprotected if(mAuthStatus == AuthStatus.Disabled.getValue() || mAuthStatus == AuthStatus.Unprotected.getValue() || mAuthStatus == AuthStatus.Authenticated.getValue() || mAuthStatus == AuthStatus.Protected_W.getValue() || mAuthStatus == AuthStatus.Protected_RW.getValue() ) { try { // if (LedFragment.getChosen()) { demo.LED(); } catch (Exception e) { e.printStackTrace(); LedFragment.setAnswer(getString(R.string.Tag_lost)); } } else { Toast.makeText(getApplicationContext(), "NTAG I2C Plus memory is protected", Toast.LENGTH_LONG).show(); showAuthDialog(); } } // =========================================================================== // NDEF Demo // =========================================================================== if (currTab.equalsIgnoreCase("ndef")) { // This demo is only available when the tag is not protected if(mAuthStatus == AuthStatus.Disabled.getValue() || mAuthStatus == AuthStatus.Unprotected.getValue() || mAuthStatus == AuthStatus.Authenticated.getValue()) { try { demo.NDEF(); } catch (Exception e) { // NdefFragment.setAnswer(getString(R.string.Tag_lost)); } } else { Toast.makeText(getApplicationContext(), "NTAG I2C Plus memory is protected", Toast.LENGTH_LONG).show(); showAuthDialog(); } } // =========================================================================== // Config // =========================================================================== if (currTab.equalsIgnoreCase("config")) { } // =========================================================================== // Speedtest // =========================================================================== if (currTab.equalsIgnoreCase("ntag_rf")) { try { // SRAM Test if ((SpeedTestFragment.isSRamEnabled() == true)) { // This demo is available even if the product is protected // as long as the SRAM is unprotected if(mAuthStatus == AuthStatus.Disabled.getValue() || mAuthStatus == AuthStatus.Unprotected.getValue() || mAuthStatus == AuthStatus.Authenticated.getValue() || mAuthStatus == AuthStatus.Protected_W.getValue() || mAuthStatus == AuthStatus.Protected_RW.getValue()) { demo.SRAMSpeedtest(); } else { Toast.makeText(getApplicationContext(), "NTAG I2C Plus memory is protected", Toast.LENGTH_LONG).show(); showAuthDialog(); } } // EEPROM Test if ((SpeedTestFragment.isSRamEnabled() == false)) { // This demo is only available when the tag is not protected if(mAuthStatus == AuthStatus.Disabled.getValue() || mAuthStatus == AuthStatus.Unprotected.getValue() || mAuthStatus == AuthStatus.Authenticated.getValue()) { demo.EEPROMSpeedtest(); } else { Toast.makeText(getApplicationContext(), "NTAG I2C Plus memory is protected", Toast.LENGTH_LONG).show(); showAuthDialog(); } } // end if eeprom test } catch (Exception e) { SpeedTestFragment.setAnswer(getString(R.string.Tag_lost)); e.printStackTrace(); } } }
先看一下傳給launchDemo函式的引數,實參是tabID,形參是currTab,也就是當前你選擇的是哪個Tab
先檢視一下,當前的認證狀態(也就是變數mAuthStatus的值)是否是Authenticated,如果是的話,執行demo的Auth函式
那麼這個demo的Auth函式是幹嘛的呢,其實就是執行一個認證的操作
你給進去一個pwd(一個byte的陣列),一個當前的認證狀態,這些在註釋裡面都有寫好
我對於你的當前的每個不同認證狀態,用條件語句進行判別,分類處理
1.Unprotected
這種狀態下,我用protectPlus函式進行處理
我把你的pwd傳進去,然後再傳進去一個Capability Container的值,這個值其實就是常數0x03,表示密碼存放在NXP NFC晶片某個暫存器的offset為0x03的位置,具體的函式實現過程待會兒細說
2.Authenticated
這種狀態下,用unprotectPlus函式去處理,這個函式不需要任何引數
3.其他認證狀態
就是這些認證狀態
這些狀態下,使用authenticatePlus函式進行進一步的認證,需要的引數是就是你給進去的pwd
上面提到的這些不同認證狀態下的認證方式的具體實現,用另外一篇文章來詳細描述