Android手机指纹因为因模板结构破损总结

1.指纹数据模板

sunwave将FingerCfgFile_t cfg_head[1] 和FingerTempCfg_t m_cfgList[5] 写入到data/system/users/sunwave/fingerCfg文件中

#模板文件结构
typedef struct FingerTempCfg {
volatile int idx;
volatile int uid;
volatile int fid;
char fileName[10]; //finger
char tempName[22];
sf_hw_auth_token_t hat;
} __attribute__((packed)) FingerTempCfg_t;

typedef struct FingerCfgFile {
int mgic;
int version;
int libVer;
int revs[4];
} FingerCfgFile_t;
typedef struct __attribute__((__packed__))

{
uint8_t version;
uint64_t challenge;
uint64_t user_id;
uint64_t authenticator_id;
uint32_t authenticator_type;
uint64_t timestamp;
uint8_t hmac[32];
} sf_hw_auth_token_t;

2.Setting UI数据

上层指纹录制UI将指纹数据存在data/system/user/0/settings_fingerprint.xml



    
  
  
  
  
  

3.指纹破损的几种情况

1>.A版本升级最新版本 (FingerTempCfg_t 四字节对齐)

fingerCfg配置文件大小:sizeof(FingerTempCfg_t * 5 + sizeof(FingerCfgFile_t)) = 608
此情况升级没有问题

2>.B版本升级最新版本 (FingerTempCfg_t 一字节对齐)

fingerCfg配置文件大小:sizeof(FingerTempCfg_t * 5 + sizeof(FingerCfgFile_t)) = 593
此情况升级没有问题

3>.A升级至B版本,未删除指纹数据,再升级至最新版本

fingerCfg配置文件大小:sizeof(FingerTempCfg_t * 5 + sizeof(FingerCfgFile_t)) = 608
此情况升级没有问题

4>.A升级至B版本,删除或录入指纹数据,再升级至最新版本

fingerCfg配置文件大小:sizeof(FingerTempCfg_t * 5 + sizeof(FingerCfgFile_t)) = 593
出错,模板配置数据被破坏

4.解决思路

目前为止没有有效的修复方法,不能直接修补破损的指纹配置文件。目前分析,可以通过判断文件大小区分当前的情况,如果升级至最新后,文件大小为608时,升级是没有问题的;当文件大小为593时,需要根据模板文件结构去解析fingerCfg的内容。

将配置文件fingerCfg打开,然后去遍历fingerCfg. cfgList[0-4]. fileName 如果fileName可以和settings_fingerprint.xml中的对应上,那就说明指纹配置文件没有被破坏。具体的fileName的值为finger1 finger2 finger3 finger4 finger5,–对应,就是finger2 finger3 finger1 finger4 finger5。

如果指纹数据被破坏,可以将 data/system/users/sunwave 下的数据和settings_fingerprint.xml中的数据清空,重启fpserver,重启设置向导让客户重新录入指纹

5.解决方法

在实现思路的过程中发现sunwave的FpServer需要读取settings_fingerprint.xml必须要加入读取的权限,但是如果要删掉settings_fingerprint.xml必须在加大权限,但是权限加大会出现其他一系列的安全问题, 例如手机因开机安全验证开不了机或是录制指纹过程中系统检测到不安全的进程强制关机等,所以Settings UI考虑还是应该在上层删掉。

FpServer大概在kernel启动后不久紧接着就会启动,settings_fingerprint.xml也需要在开机前删掉,因为在开机后删掉Settings直接读取缓存将将不会更新UI,所以需要有一个进程需要在kernel启动后再开机之前做到判断指纹模板是否受损删掉指纹受损文件更新Settings UI同时启动设置向导一系列的工作,而AMS(ActivityManagerService)就很好满足了我们的这个需求,该服务在SystemServer启动后不久启动,比开机广播发出要早。

/*在AMS中可以通过调AuthenticationCallback接口来实现AMS与sunwave的FPServer上层与底层之间的交互
   FPServer通过该接口向上层传值acquireInfo来说明指纹模块是否受损
   当acquireInfo == 88时说明文件受损,当acquireInfo == 99说明文件完好,
   当acquireInfo是其他值时说明底层这时还没有处理判断完,会有一定的延迟,大概是12ms
   接口拿不到返回值所以需要继续调直到有返回值
   这里有一个安全隐患,如果返回值是88的话FPServer便会毫不犹豫的删掉指纹底层模板
   并且返回值至下一次开机前都不会改变,所以在接收到88或99后需要立即关闭调用接口的通道
*/
    private FingerprintManager.AuthenticationCallback mAuthCallback = new FingerprintManager.AuthenticationCallback() {
        @Override
        public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {

        }

        @Override
        public void onAuthenticationFailed() {

        };
        @Override
        public void onAuthenticationError(int errMsgId, CharSequence errString) {
            Log.i("sunwave", "onAuthenticationError errMsgId = " + errMsgId);
        }

        @Override
        public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {

        }
         public void onAuthenticationAcquired(int acquireInfo) {
            Log.i("sunwave", "onAuthenticationAcquired acquireInfo = " + acquireInfo);
            if (acquireInfo == 88 ) {
            //文件受损
            isFirstdelFig = false;//关闭通道
            runOBE = true;
            mErrMsg = false;
            startOOBE();
            }else if (acquireInfo == 99){
            //文件完好
              isFirstdelFig = false; //关闭通道
              mErrMsg = true; 
            }
        }
    };

我们可以直接在AMS的startHomeActivityLocked中执行调用该接口的方法,因为该方法在每次有Activity创建时都会执行,安全,有效还可以防止过早于FPserver执行而被遗漏

private boolean getFingerIsDamaged(){
     mFingerprintManager.authenticate(null,mFingerprintCancel,147852369,mAuthCallback,null);
     mFingerprintCancel.cancel();
    Log.e("sunwave","----getFingerIsDamaged-------mErrMsg ="+mErrMsg);
     return mErrMsg;
}

因为AuthenticationCallback是公共接口,为了防止其他程序调用该接口而引起指纹误删所以我们需要调用该接口时加一个特有的tag = 147852369;该tag只有一个目的就是只有我们调用时才允许执行删除指纹的操作

由于权限的问题的限制,删除指纹Setting UI的操作只能在FPS(FingerPrintService)中执行,我们可以通过重写FPS中的handleAcquired方法来实现这一目的,因为我们在调用AuthenticationCallback时同时它也会向FPS发消息,我们可以通过acquireInfo和tag的双重过滤来保证删除效果的安全性

    protected void handleAcquired(long deviceId, int acquiredInfo) {
    ClientMonitor client = mCurrentClient;
    if (client != null && client.onAcquired(acquiredInfo)) {
        removeClient(client);
    }
    //add 
    Log.e("sunwave","FingerprintService acquiredInfo ="+acquiredInfo);
    if (acquiredInfo == 88 && auth_flag == 147852369) {
    //同时需要注意该auth_flag同样需要在FPS的authenticate方法中进行注册,否则无法得到tag
        List list= mFingerprintUtils.getFingerprintsForUser(mContext, mCurrentUserId);
        for(int i = 0;i < list.size(); i ++){
            int fingerId = list.get(i).getFingerId();
            Log.e("sunwave","FingerprintService fingerId ="+fingerId);
            mFingerprintUtils.removeFingerprintIdForUser(getContext(), fingerId,
                    mCurrentUserId);
        }
    }
}

这样就可以实现在开机前调接口实现指纹破损的判断,并删除破损指纹文件的操作,因为加入了标记,所以也保证了不会因为过多的调用接口而误删指纹的安全性

你可能感兴趣的:(技术总结)