項目需求討論- 讓APP知道是用哪一個指紋來支付和解鎖

之前我寫過相關的指紋解鎖的文章:前端

傳送門: 項目需求討論-APP手勢解鎖及指紋解鎖
那時候作的APP解鎖是調用系統的指紋解鎖功能,同時,進行指紋驗證的時候,只要是手機中錄製過的指紋,而後在指紋驗證過程當中就會認爲認證成功。但僅僅這樣,很難知足一些驗證要求比較高的APP,好比支付類型的APP。否則我不是本人。我是女友啊,或者誰,我在你手機裏有個指紋,爲了方便解鎖屏。又或者,通常朋友玩你的手機,問你鎖屏密碼,你也會說出來,畢竟想一想是鎖屏密碼,而後去設置裏面添加指紋也只須要鎖屏密碼,這時候那個朋友偷偷去錄了個本身的指紋,豈不是你的指紋驗證就形同虛設了。豈不是也就立刻掌握你的支付帳戶了。android

我來講下支付寶的指紋相關方式:

前提:我手機上有左右大拇指的指紋已經錄製好了ios

  1. 你到支付寶的設置界面,開啓指紋支付功能,這時候會跳出彈框,讓你驗證指紋:

    這時候若是我用右邊的指紋來進行驗證,這時候指紋驗證經過了。就讓你進行密碼驗證,證實你這個指紋的人同時也是知道密碼的。

    你輸入完正確的密碼後,算是正式的綁定上了。就表明你這個指紋具備相應的支付功能。
  2. 到了支付界面,咱們用右手拇指去支付,OK,確定是沒問題的,若是這時候我故意用左手的拇指去支付,會出錯:

    那就說明,咱們的指紋具備一個id值,能讓服務器那邊知道當前這個指紋是否是咱們綁定的指紋。

順便提一句,ios我試了下,當你在手機添加了一個指紋後,他就會不讓你進行支付,好比咱們原來是右手拇指支付的,當你添加一個新的指紋後,就算你用右手指紋去付錢,也不行,因此這裏我認爲ios是監聽了系統指紋的變化狀況,好比新增了指紋。而不只僅單純是判斷到底具體是哪個指紋git


這個可是咱們知道咱們指紋驗證經過的都是系統底層的API,咱們的API最後返回驗證結果給咱們的內容中,是否帶有相關的參數,咱們能夠繼續往下看:程序員

在個人文章 項目需求討論-APP手勢解鎖及指紋解鎖 我提過,最後指紋驗證經過是回調:github

@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
    .....
    .....
    .....
}複製代碼

咱們能夠看到指紋驗證經過後的回調方法參數是FingerprintManager.AuthenticationResult,咱們再來看下這個類json

public static class AuthenticationResult {
    private Fingerprint mFingerprint;
    private CryptoObject mCryptoObject;

    /**
     * Authentication result
     *
     * @param crypto the crypto object
     * @param fingerprint the recognized fingerprint data, if allowed.
     * @hide
     */
    public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint) {
        mCryptoObject = crypto;
        mFingerprint = fingerprint;
    }

    /**
     * Obtain the crypto object associated with this transaction
     * @return crypto object provided to {@link FingerprintManager#authenticate(CryptoObject,
     *     CancellationSignal, int, AuthenticationCallback, Handler)}.
     */
    public CryptoObject getCryptoObject() { return mCryptoObject; }

    /**
     * Obtain the Fingerprint associated with this operation. Applications are strongly
     * discouraged from associating specific fingers with specific applications or operations.
     *
     * @hide
     */
    public Fingerprint getFingerprint() { return mFingerprint; }
};複製代碼

這個類很簡單,裏面就二個屬性值:FingerprintCryptoObject,咱們再來看Fingerprint類的內容:小程序

/**
 * Container for fingerprint metadata.
 * @hide
 */
public final class Fingerprint implements Parcelable {
    private CharSequence mName;
    private int mGroupId;
    private int mFingerId;
    private long mDeviceId; // physical device this is associated with

    ....
    ....
    ....

}複製代碼

沒錯。裏面有mFingerId等參數。豈不是咱們直接拿這個值不就好了??這麼簡單???api

答案固然是No,由於你回頭再看上面的AuthenticationResult類裏面的getFingerprint()方法上面用@hide修飾了,並且咱們的Fingerprint類上面也用@hide修飾了。安全

可是你們內心必定會想,那我不是用反射來調用getFingerprint()方法拿到Fingerprint對象,從而再來拿mFingerId不就行了。

好比我在這裏寫上反射獲取:

@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
    mErrorTextView.removeCallbacks(mResetErrorTextRunnable);
    mIcon.setImageResource(R.drawable.ic_fingerprint_success);
    mErrorTextView.setTextColor(
            mErrorTextView.getResources().getColor(R.color.success_color, null));
    mErrorTextView.setText(
            mErrorTextView.getResources().getString(R.string.fingerprint_success));
    mIcon.postDelayed(new Runnable() {
        @Override
        public void run() {
            mCallback.onAuthenticated();
        }
    }, SUCCESS_DELAY_MILLIS);

    //經過反射來獲取
    try {

        Method method1 = result.getClass().getMethod("getCryptoObject");
        Object cryptoObject = method1.invoke(result, new Object[]{});

        Method method2 = result.getClass().getMethod("getFingerprint");
        Object fingerPrint = method2.invoke(result, new Object[]{});

    } catch ( NoSuchMethodException e ) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}複製代碼

你會發現就算經過反射來拿Fingerprint對象,拿到的也是null。而我用一樣的代碼來拿CryotoObject對象就是有內容的。

因此這裏咱們用反射也出現了問題,那咱們本身普通程序員開發應該怎麼來處理呢。
(ps:StackOverflow上也有人提出相同的問題:Fingerprint爲null,他是直接把android.jar包換了。換成了這裏沒有@hide修飾了。這樣就能夠直接在代碼裏面使用,可是拿到的也是null。)


主角: Tencent/soter

TENCENT SOTER是騰訊於2015年開始制定的生物認證平臺與標準,經過與廠商合做,目前已經在一百餘款、數億部Android設備上獲得支持,而且這個數字還在快速增加。

目前,TENCENT SOTER已經在微信指紋支付、微信公衆號/小程序指紋受權接口等場景使用,並獲得了驗證。

接入TENCENT SOTER,你能夠在不獲取用戶指紋圖案的前提下,在Android設備上實現可信的指紋認證,得到與微信指紋支付一致的安全快捷認證體驗。

爲何要用TENCENT SOTER:

這裏能夠對比下系統原生Android 6.0指紋接口和FIDO方案。

TENCENT SOTER Android Framework FIDO
安全性 高(先後臺支持,有產線生成一機一密根密鑰) 低(手機被root後易被破解,且沒法準確檢測root) 高(先後臺支持,有產線生成根密鑰)
接入成本 較低(前端極輕量級sdk,後臺無須集成sdk) 低(無需先後臺sdk) 高(部署複雜)
敏感業務可用 是(可獲取本機指紋索引) 否(沒法獲取指紋在本機索引,有盜用風險) 是(可獲取本機指紋索引)
用戶隱私保護 好(不會獲取指紋圖案) 好(不會獲取指紋圖案) 好(不會獲取指紋圖案)
商業隱私保護 好(驗證無須請求到中心服務) \ 較差(須要每一筆驗證都請求到中心驗證服務器)

固然最主要的功能是:
同時,對比與原生接口,也有兩個明顯優點:
支持部分Android L(Android 5.0、5.1)機型指紋認證
能夠提供本次認證在本機上的指紋索引以區分手指

更多請看:什麼是TENCENT SOTER
SOTER支持的機型:SOTER 指紋支持機型


因此咱們看到了。它能夠提供本機上的指紋索引來區分手機。

咱們使用github soter上面提供的Demo。咱們能夠運行demo,這時候出現一些狀況:

  1. 有些人運行demo,可能會開啓指紋功能的時候會失敗,多是你的機型不支持。我使用小米5不行,使用的OPPO A57就能夠了。
  2. 你們可能看到華爲上面一臺都沒有。在issue裏面咱們也看到了。騰訊正在和華爲洽談,並且說了技術上面是沒有任何問題的。因此後續你們也能夠不用擔憂
  3. 最後你用指紋解鎖的時候,能夠再回調函數中查看相關的log信息:
    soterdemo: use fingerprint payment result: total: SoterCoreResult{errCode=0, errMsg=''}, extData: SoterSignatureResult{rawValue='I'm a demo challenge string', fid='3374914681109099800', counter=42, TEEName='QSEE', TEEVersion='4', FpName='fingerprint', FpVersion='1', cpuId='000000000006b0e13a925a082575ca3e', saltLen=20, jsonValue='{"raw":"I'm a demo challenge string","fid":"3374914681109099800","counter":42,"tee_n":"QSEE","tee_v":"4","fp_n":"fingerprint","fp_v":"1","cpu_id":"000000000006b0e13a925a082575ca3e","uid":"10107"}', signature='J7jNgKFc2TMExrx3dLJAiAFF25cwZvUhGWLQJPhhbHKsHTLi+/eAsJd7gmgAJnZsCQrHq2vnIeW8j0Rj81aRbF1Svv5tNRJt1Gyzewu9Lpa7E5rwTJ97otJPWv3b3nxyDicYQaEZbzqGSYeKga+tUutDlISzvFOLqrikX/OT0W5M0/szFIpkrEAJiMGYNqg451iijN3dM6pB9AXgs6qohz25sWbF6OEthvAO9hI9Ddsm5bn69Ct/3f4eaB3eb/Ljo/Hs8YK//UhkvXn4OcOsnsmHZ6P6jaNcC60iylxxLuPc2PwMd8dRPDKk8S0HEyjT7SpaQqIO2j7/hbi2by0QJg=='}, signature data is: SoterSignatureResult{rawValue='I'm a demo challenge string', fid='3374914681109099800', counter=42, TEEName='QSEE', TEEVersion='4', FpName='fingerprint', FpVersion='1', cpuId='000000000006b0e13a925a082575ca3e', saltLen=20, jsonValue='{"raw":"I'm a demo challenge string","fid":"3374914681109099800","counter":42,"tee_n":"QSEE","tee_v":"4","fp_n":"fingerprint","fp_v":"1","cpu_id":"000000000006b0e13a925a082575ca3e","uid":"10107"}', signature='J7jNgKFc2TMExrx3dLJAiAFF25cwZvUhGWLQJPhhbHKsHTLi+/eAsJd7gmgAJnZsCQrHq2vnIeW8j0Rj81aRbF1Svv5tNRJt1Gyzewu9Lpa7E5rwTJ97otJPWv3b3nxyDicYQaEZbzqGSYeKga+tUutDlISzvFOLqrikX/OT0W5M0/szFIpkrEAJiMGYNqg451iijN3dM6pB9AXgs6qohz25sWbF6OEthvAO9hI9Ddsm5bn69Ct/3f4eaB3eb/Ljo/Hs8YK//UhkvXn4OcOsnsmHZ6P6jaNcC60iylxxLuPc2PwMd8dRPDKk8S0HEyjT7SpaQqIO2j7/hbi2by0QJg=='}複製代碼
    其中比較重要的就是fid='3374914681109099800',不一樣的指紋,這個ID值是不一樣的。因此咱們能夠用來判斷了。

仍是那句老話,可能我哪裏講的不對。你們請下面留言。多回復多點贊。哈哈。

相關文章
相關標籤/搜索