指紋登錄是怎麼跑起來的

現在指紋登錄是一種很常見的登錄方式,特別是在金融類APP中,使用指紋進行登錄、支付的特別多。指紋登錄本身是一種指紋身份認證技術,通過識別當前用戶的指紋資訊,進而確認用戶在系統內的註冊身份。

指紋認證得以流行,我認為有兩個關鍵點:

一是簡便,沒有了忘記密碼的煩惱,也免去了輸入密碼的繁瑣。

二是安全,能夠用在支付環節,這就說明其可以達到金融級別的安全。

這篇文章就來簡單看下指紋認證是如何做到以上兩點的,其中有哪些坑,有哪些坎。

指紋識別的原理

指紋認證的歷史其實是很悠久的,在中國唐代指紋已經廣泛應用於文書契約,宋代手印已正式成為刑事訴訟的物證,這說明人們早就認識到了個體指紋的獨特性,並且有了成熟的識別方法。對於電腦指紋識別,也是去尋找指紋的獨特性,這裡僅做簡單的介紹:

有一個關鍵概念:指紋特徵點,常見的特徵點有指紋中的端點和分叉點,演算法中通常記錄它們的位置和方向。程式通過光學感測器採集指紋影像,提取指紋特徵點,用數學表達式描述它們,稱為指紋模版。註冊指紋時把指紋模版保存到資料庫或其它存儲中;驗證指紋時,先提取當前指紋的特徵點,再和已記錄的指紋模版進行比對,匹配度達到一定的閾值就算匹配成功。

WX20220103-130711@2x

對於指紋識別的兩個安全問題:

  • 指紋影像泄漏問題:程式可以不保存指紋影像;指紋模版進行某種加密處理後,可以做到無法還原出指紋影像。當然能做和做不做是兩碼事。指紋泄漏還有另一種情況,2014年德國黑客從照片中成功提取了德國國防部長的指紋,所以以後拍照時不要比劃剪刀手了,但是大部分人的賬戶應該不值得冒著巨大的風險、花費很大的力氣這樣搞,所以平常也不用太擔心,注意下就行了。

  • 假指紋識別問題:萬一指紋被別人採集到了,或者製作成了指模,是不是就可以暢通無阻了呢?對應這類問題,有活體指紋檢測技術。硬體上採用電容感測器採集溫度、心率等數據,加上光學感測器的指紋紋路數據,進行綜合判斷;軟體上的實現則一般通過機器學習的方式進行識別。但是兩者對假指紋的識別率可能都不太理想,可見的廠商宣傳也不多,其中原因可能是因為仿生技術太牛逼了,這裡也沒找到太多有價值的資訊。實際應用在金融領域時,金融服務商必然採取了更多的手段來降低安全風險,而不是單純的看指紋認證結果,畢竟出了問題生意可能就做不下去了,所以大規模應用時的安全風險應該是有所控制的。

門禁中的指紋認證

在移動設備廣泛採用指紋認證之前,這一技術已經得到了大範圍的應用,很多人應該都接觸過刷指紋的門禁或者考勤機。從老闆的角度看,刷指紋比刷卡更能有效的驗證員工的身份,而且成本也不高。從員工的角度看,不用多帶一張卡,更方便高效。從安全的角度考慮,指紋識別技術比較成熟,只要不泄漏,一般也不會出問題,設備做得好安全性還更高一些;出問題也僅在門禁這個環節,即使沒有指紋認證,也有別的方法開門,複製門禁卡或者鑰匙可能更方便;對於更重要的保護對象,應該還有更安全的的保護措施。

在門禁中使用指紋一般是先註冊,將用戶和指紋進行綁定,提取出的指紋特徵數據就保存在本地,具體註冊過程如下圖所示:

指紋註冊流程

當用戶需要開門時,在指紋機刷指紋,指紋機會提取當前指紋的特徵值,然後和本地存儲的指紋數據進行一一比對,如果匹配度達到一定的閾值,則指紋識別成功,向門禁下達開門指令,具體認證過程如下圖所示:

本機指紋認證流程

APP中的指紋認證

這裡說的APP指的是移動設備系統中的第三方應用,移動設備系統特指當前比較流行的Android和iOS等手機作業系統。

APP中的指紋認證目前常見於登錄或者支付功能,因為涉及到APP自身的用戶和業務數據操作,必然需要和APP後端服務進行交互,基於安全考慮,客戶端和服務端之間也需要進行身份認證,所以APP中的指紋認證被分成了兩部分:手機本地認證和遠程認證。

本機認證

手機系統本身的指紋認證和門禁系統中的指紋認證並無本質區別:用戶首先錄入指紋,基於安全考慮,指紋的特徵數據也是保存在手機本地;使用指紋進入系統時也是先提取當前的特徵值,然後和本地的指紋庫進行比對,匹配上了就能進手機入系統。

和門禁系統不同的一點是,手機中用戶需要有一個能進入系統的密碼,可以是字元密碼,也可以是手勢密碼,當用戶的指紋無法使用時(可能是指紋模組故障,也可能是用戶指紋問題),仍然能有其它方式進入手機;門禁系統中用戶則可以只有指紋認證這一種方式,進不了門時,還可以找管理員。

當然只使用手機本地認證也是有意義的,每次APP從後台切換到前台時都需要用戶刷指紋,以驗證當前操作用戶的身份,很多的銀行APP就是這樣做的(其實我並未確認這些APP此時有沒有去後台再次驗證,只是認為這是一種有意義的認證方式)。

本機認證的安全性手機作業系統廠商們已經做的很好了,指紋的註冊和識別都在安全區域內進行,指紋識別的結果可以加密的方式返回給APP,這塊直接應用就可以了。

遠程認證

遠程認證就是客戶端和服務端之間的認證,完整的方式就是雙向認證:客戶端要驗證服務端的身份,以免被套取資訊;服務端要驗證客戶端的身份,以免用戶身份被冒充。

  • 客戶端驗證服務端的身份:現在都使用https了,https證書就是服務端身份的保證,至少可以保證訪問到地址就是你想訪問的域名地址,高級點的證書還能標識證書所有者的身份;使用https時數據也是加密傳輸的,所以一般應用場景是沒問題的。但是也發生過濫發證書的情況,所以如果需要更高的安全級別,服務端可以再生成一對非對稱密鑰。公鑰發給APP,私鑰自己保存好,每次認證時,客戶端先採用服務端的公鑰對數據進行加密,然後再發送出去,服務端再採用自己的私鑰進行解密,如此假冒的服務端就不能解密數據,就什麼也得不到;服務端返回給客戶端的數據帶上私鑰對數據的簽名,客戶端可以驗證簽名,驗證通過則代表是服務端返回的,就可以應用這些數據。

  • 服務端驗證客戶端的身份:也是通過非對稱密鑰的方式,客戶端生成一對非對稱密鑰,私鑰自己保存好,公鑰發送到服務端。指紋認證通過後客戶端使用私鑰對請求參數進行簽名,然後再發送出去,服務端使用客戶端公鑰對接收到的數據簽名進行驗證,如果驗證通過,則說明數據沒有被篡改,可以處理客戶端發起的業務請求。

開啟指紋認證

這裡以登錄為例,來看看如何使用指紋認證來做APP登錄。還是先要註冊指紋,具體過程如下圖所示:

APP開啟指紋認證流程

  • 5開啟指紋:開啟指紋登錄的時機,一般都是先用別的方式登錄了APP,然後再開啟指紋登錄。但是也有一些例外,用戶使用APP時直接使用第三方登錄,第三方提供了指紋登錄的方式,比如使用Apple Id登錄。上邊圖中是先用帳號密碼登錄了系統,然後才開啟的指紋認證。
  • 12對比系統存在的指紋:指紋數據始終保存在手機本地,不會上傳到遠程。目前市面上的手機都是這樣做的,Android和iOS提供的指紋認證API都只返回true或者false的認證結果,這樣可以避免雲服務被攻破時導致大規模泄漏的嚴重後果,最大限度的保護用戶生物特徵數據的安全。
  • 13指紋驗證成功:本地指紋認證通過就代表用戶身份驗證通過,不管是哪個手指。早期的作業系統版本中可能能夠獲得是使用的哪個指紋,但是現在一般都不開放了,只能得知指紋集是否發生了變化(刪除或者添加了指紋),此時App可以強制用戶退出,再使用其它安全的方式登錄,然後再讓用戶決定是否開啟指紋,支付寶就是這樣做的。
  • 重放攻擊問題:步驟16中的請求可能被人截獲,雖然無法解密,但是可以多次發向服務端,造成重放攻擊的問題,可以引入一個挑戰碼來解決這個問題。步驟8初始化指紋註冊請求時服務端可以生成這個挑戰碼,然後在步驟16中攜帶這個挑戰碼,然後在服務端進行驗證。

使用指紋認證

下邊再來看下使用指紋登錄的過程:

APP指紋認證登錄流程

  • 登錄時的本機指紋認證和註冊時的本機指紋認證方法相同,只不過這次是在用戶選擇指紋登錄時彈出指紋刷取頁面。
  • 10簽名登錄數據:主要是用客戶端私鑰簽名設備的唯一標識和挑戰碼,在開啟指紋認證時指定了必須採用指紋授權的方式才能使用私鑰,這樣能確保簽名是由認證過的用戶發起的(準確的說是手機上登錄過指紋的所有用戶,在開啟指紋認證時已經提示用戶所有錄入的指紋都將可以用來登錄,同時如果指紋發生變化,會讓用戶重新確認,所以可以認為他們都是有許可權的用戶);服務端如果驗證簽名通過,則代表數據在傳輸過程中沒有被篡改,登錄是在可信的客戶端發起的;前後端的認證結果結合起來就代表登錄是由認證過的用戶發起的。
  • 在開啟指紋階段,已經將設備唯一標識、客戶端公鑰綁定到了用戶記錄,所以簽名驗證通過後,就可以生成當前用戶的登錄Token,並在後續的客戶端與服務端的一般交互中使用這個Token。在關鍵的交互,比如支付中,還是要使用指紋認證這種安全性更高的方式。

以上就是APP中的指紋認證原理,指紋登錄和指紋登錄的過程差不多,只不過支付需要更高的安全等級,指紋認證可以滿足這個安全要求。

客戶端身份認證的問題

在上文APP的指紋註冊階段,客戶端生成了一對非對稱密鑰,用於後續服務端認證客戶端的身份,這個密鑰在當前的手機中已經有了成熟的安全存儲和使用方法,這就是TEE(可信執行環境):

客戶端私鑰被TEE安全密鑰加密存儲在手機中,目前沒有破解之法;同時還可以指定只有通過了本機指紋認證才能使用私鑰對數據進行簽名和加密;再者如果手機中加入了新的指紋或者刪除了指紋,存儲的私鑰就會失效;所以密鑰的存儲和使用是可以保證安全的。

但是還存在其它的安全隱患:

1、服務端無法確認上傳的客戶端公鑰能否代表客戶端身份,任何程式都可以生成一對非對稱密鑰,然後對數據進行簽名,再把公鑰一起發到服務端,服務端僅能驗證簽名的正確性,但是無法驗證公鑰的來源,也就無法驗證客戶端的身份。某些解決方案中會在客戶端集成一個認證器SDK,這個SDK生成的認證資訊中會攜帶一些特殊識別資訊,而且每個應用每個機器不同,很難破解,後端可以據此判斷是在集成了認證器SDK的應用中發起的。但是也有一些難題,識別資訊的生成方法可能會被破解,還有怎麼確認是用戶發起的還是惡意程式發起的?

2、密鑰生成過程中可能被黑客替換,存儲和使用再怎麼安全也無濟於事了。這個在微信的技術資料中提到過,Android的密鑰生成有被攔截的可能,不確定當前是不是解決了。這也說明底層框架和作業系統也可能是不可信的,在某些場景下必須慎重考慮。

密鑰生成被攔截

3、以上兩個問題在Root或者越獄之後的手機中更嚴重,APP、SDK和作業系統都無法信任了,所以很多金融類APP不支援在Root或者越獄的手機上使用指紋認證,不過道高一尺魔高一丈,還是有一些方法來欺騙APP,這也不乏部分用戶的支援(自作X啊)。

這個問題有好的辦法解決嗎?有,設備出廠前就把私鑰保存到TEE中。

Android中的密鑰安全

大家應該知道Android系統是開源的,很多手機廠商都在生產Android手機,市面上有多個廠商在競爭,誰也不服誰,所以要想推廣上文提到的出廠前內置私鑰的方法,就必須統一標準。在中國騰訊和阿里具備這樣的影響力,騰訊搞了SOTER,阿里搞了IFAA,兩者都要求手機廠商在產線上生成一對非對稱密鑰,私鑰寫入手機TEE,即使拿到了手機當前也沒有破解之法,私鑰也就不會被泄漏,除非手機廠商搞事情,不過如果手機廠商真的這樣做了,就離倒閉不遠了;公鑰上傳到認證伺服器,認證的時候用於驗證手機APP上傳的數據簽名,驗證通過了就能代表是在對應的手機發起的認證。

同時為了推廣這個技術,這種協議還支援別的廠商APP接入進來。但是這樣就很容易泄漏APP的商業隱私 ,比如SOTER每次支付都要去騰訊的認證伺服器認證一下,據此就可以推斷你的業務行為和交易量,所以SOTER又搞了應用密鑰和業務密鑰,來盡量消除這個商業風險;同時針對Android密鑰生成可能被攔截的問題,讓手機廠商裝個修補程式包就解決了,比如替換掉不安全的中間環節。下邊來看下應用密鑰和業務密鑰的產生過程。

應用密鑰產生流程:應用密鑰在應用首次安裝的時候生成,應用密鑰的私鑰保存在手機端,並使用出廠前內置的私鑰簽名,然後發到騰訊的認證伺服器驗證簽名,此時應用密鑰的公鑰會保存到應用的後台。

APP應用密鑰產生過程

業務密鑰產生流程:在使用登錄或者支付的指紋認證註冊的時候,應用會再生成一個業務密鑰,業務密鑰的私鑰還是保存在手機端,業務密鑰使用手機端的應用密鑰進行簽名,驗證也只需要在應用的後台驗證就可以了,此時和騰訊的認證伺服器就沒有關係了。

APP業務密鑰產生過程

這樣騰訊就不知道你的實際業務運營情況了,比如每天在線支付多少筆,但是APP安裝量還是免不了會暴漏出來,話說APP都要上應用市場的,這個資訊其實早就公開了。

關於SOTER詳細介紹,可以看官方文檔://github.com/Tencent/soter/wiki

IFAA的應用過程和SOTER差不多,這裡就不再贅述了。另外國外還有一個FIDO聯盟,也是解決這個問題的,中國是聯想集團的子公司國民認證在推廣這個,技術原理也都差不多。

iOS中的密鑰安全

iPhone的作業系統和硬體都是自己控制的,所以對於安全控制它可以做的很好。

對於本機指紋認證,蘋果也提供了Touch ID的API,可以在前端調用指紋認證,但是如果要發送到服務端去驗證,基於各種安全考慮,就還是需要一個客戶端密鑰,這個客戶端密鑰有沒有安全的產生方式呢?我沒有找到官方的文檔說明,很多基於這個方案的第三方應用可能都是自己生成的吧,盡量做到安全。當然這個也是猜測。

但是微信或者支付寶這種應用怎麼能忍呢?SOTER曾經說要支援iOS,最後也是不了了之;IFAA宣傳的是兼容支援iPhone 5s 以上所有 iOS 手機,不過它不開源。可能蘋果最終還是不想把這塊放開,同時基於蘋果的強勢地位,最有可能是蘋果專門給這種應用開放了特定的API,不許外傳。

如果是做指紋登錄,其實可以直接使用蘋果開放的Apple ID登錄協議,支援指紋和刷臉認證,會給應用返回認證Token和授權碼,應用後台拿著這兩個再去找蘋果驗證。從這個邏輯上看,蘋果的後台必然能安全的確認發起請求的客戶端身份,所以估計和Android的原理差不多,只不過前後端的每次認證都得蘋果來驗證。

Web中的指紋認證

上面提到過一個FIDO聯盟,它和W3C搞了一個WebAuthn標準,它的目的是標準化用戶對基於 Web 的應用程式和服務的公鑰認證的介面,說人話就是定了一個Web程式中使用公鑰認證的標準,所謂的公鑰認證就是上文提到的客戶端密鑰認證技術。這個中國產品好像使用的不多見,不過這件事挺牛的。它可以在Windows、Linux、Mac OS、Android、iOS、智慧手錶等各種設備中使用指紋識別、面部識別、虹膜識別、聲音識別、實體密鑰(USB連接、藍牙連接、NFC連接)等多種方式進行認證,儘可能的擺脫對密碼的依賴。

這個技術標準和APP中的公鑰認證技術是一脈相承的,主要區別在於APP換成了瀏覽器,認證模組除了作業系統本身支援,還增加了對專用硬體的支援。有興趣的可以去了解下。


以上就是本文的主要內容,因能力有限,可能存在部分錯漏,歡迎指正。

收穫更多架構知識,請關注公眾號 螢火架構。原創內容,轉載請註明出處。