1. 程式人生 > >Android程式執行分析——中等複雜程度的NTAG I2C Demo為例(二)

Android程式執行分析——中等複雜程度的NTAG I2C Demo為例(二)

本節主要討論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

上面提到的這些不同認證狀態下的認證方式的具體實現,用另外一篇文章來詳細描述