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);
        }
    }
}

這樣就可以實現在開機前調接口實現指紋破損的判斷,並刪除破損指紋文件的操作,因為加入瞭標記,所以也保證瞭不會因為過多的調用接口而誤刪指紋的安全性

You May Also Like