本节主要讨论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
上面提到的这些不同认证状态下的认证方式的具体实现,在另外一篇文章详细描述
https://blog.csdn.net/qq_24118527/article/details/82950796