我有自覺自己在重複使用密碼。即便如此,今天我大概還是會一邊想著「嗯,自己應該沒問題吧」,一邊把 8 碼密碼輸入某個服務。這樣的人,應該意外地不少吧。
最近,在 Google、Apple,以及主要的電商服務等地方,開始常常看到「使用通行密鑰登入」這個選項。常見的說明是,可以用指紋或臉部辨識登入,很方便。但你應該也曾懷疑過:「這不過就是把指紋資料送到伺服器而已吧?」這篇文章想先從回答這個疑問開始。
密碼驗證的機制很單純。使用者和伺服器都知道相同的一串字元,登入時再拿來比對。就這樣而已。
而這種單純,正好就是弱點。即使伺服器端不是儲存字串本身,而是儲存雜湊值,「把使用者輸入的值送到伺服器」這個步驟本身並沒有改變。送到真正的伺服器當然沒問題,但如果送到的是做得惟妙惟肖的假網站呢?使用者會不疑有他地輸入,密碼就直接落入攻擊者手中。這就是網路釣魚。
伺服器端也有外洩的途徑。即使經過雜湊處理,如果演算法薄弱,或是密碼重複使用,還是可能被破解。簡單說,密碼這種方式,本身就建立在「把秘密字串四處傳送、四處儲存」這個前提上,這個前提本來就很勉強。
通行密鑰的核心,在於使用公開金鑰密碼學,完全不把私鑰送到伺服器的設計。
在註冊時,裝置(智慧型手機或 PC 的認證晶片)會當場生成一對公鑰與私鑰。送到伺服器的只有公鑰。私鑰通常會透過 iPhone 或 Android 的 iCloud 鑰匙圈、Google 密碼管理工具等機制,以加密狀態同步到多個裝置上(synced passkey,同步式通行密鑰)。另一方面,像硬體安全金鑰這類專用裝置,私鑰則是一次都不會從裝置中物理性地離開(device-bound passkey,裝置綁定式通行密鑰)。這兩種方式的共通點是:私鑰從來不會以明文形式透過網路傳送。
我們來看登入時的流程。
在這裡,指紋或臉部辨識只是「為了確認本人而解鎖裝置」的手段而已。生物資訊從頭到尾都不會送到伺服器。等裝置本機完成比對後,真正運作的只有私鑰的簽章。
送出的,永遠是針對不同 challenge 的不同簽章。這也是它能防範網路釣魚的原因。就算假網站再怎麼像真的,只要它不是綁定真正網站網域的情境,就無法成立有效簽章。瀏覽器與作業系統會比對註冊時的網域與目前正在存取的網域;如果不一致,簽章流程根本不會開始。使用者「一不小心被騙」的空間,在設計上就已經被堵住了。
回到一開始的疑問。如果伺服器端資料庫外洩,通行密鑰會怎麼樣?
外洩的只有公鑰。公鑰顧名思義就是可以公開的值,僅靠這個無法偽裝登入。攻擊者真正想要的是私鑰,但它從來沒有經過伺服器。就算成功入侵伺服器,拿到的也什麼都沒有。
這不只是「比雜湊密碼更安全」而已。攻擊者能奪取的對象本身就不同。密碼方式的重點在於「保護秘密」,但通行密鑰的設計則是把前提改成「一開始就不要把秘密放在伺服器端」。要保護的東西越少,防守方式就越單純。
不過,這裡說的「就算被竊也沒意義」,是指登入目標服務(RP:Relying Party)的伺服器外洩這種情況,並不是無條件成立的說法。如果混淆了這個範圍,整個討論就會偏掉。
雖然私鑰不會送到伺服器,但如果是 synced passkey(透過 iCloud 鑰匙圈或 Google 密碼管理工具等,將密鑰同步到多個裝置的類型),私鑰本身會以加密狀態透過通行密鑰提供者的帳號進行同步。也就是說,私鑰的實體並不是分散在各個裝置上,而是集中到「通行密鑰提供者的帳號」這個單一位置。
如果這個帳號本身(例如 Apple ID 或 Google 帳號)被盜,攻擊者就能存取同步過來的私鑰,進而接管所有使用該通行密鑰的網站登入。這是一條完全不經過 RP 伺服器的攻擊路徑,和「不把私鑰送到伺服器」這個設計並不衝突,卻仍然能成立。
相對地,像硬體安全金鑰這類 device-bound passkey,因為私鑰從來不會離開裝置,所以從原理上就沒有這條風險路徑。
因此更精確地說,通行密鑰「就算被竊也沒意義」,是針對 RP 伺服器遭入侵而言;而如果使用 synced passkey,真正需要保護的對象,與其說是「每個服務的密碼」,不如說是「通行密鑰提供者的帳號」更貼近實際。也就是說,應該替通行密鑰提供者的帳號設定強驗證(最好是 device-bound passkey 或其他 MFA)。
老實說,我第一次接觸通行密鑰時,腦中先浮現的是「這樣換機的時候不就完蛋了嗎」的焦慮。實際上,在從舊智慧型手機換機時,通行密鑰沒有同步過去,導致一部分服務無法登入,最後還是得回頭走密碼復原流程。
這段經驗讓我感受到的,不是通行密鑰本身的安全性,而是「把私鑰放在離網路多遠的位置」這個設計,和可用性之間是有取捨的。密碼是以「只要記得就能到處用」這種粗暴便利,換來任何裝置都能復原;通行密鑰則是以「不把私鑰送到伺服器」的潔癖,換來如果是 synced passkey,就得把可用性交給雲端同步機制;如果是 device-bound passkey,則得把可用性交給裝置本身的持有與管理。我也覺得,對同步基礎建設與裝置管理的依賴,實際上就是通行密鑰運用上的弱點。
即便如此,能在設計層級上讓網路釣魚失效,這點在實務上還是很重要。過去處理過的內部系統,因為擔心被魚叉式網路釣魚竊取憑證,所以疊了很多層 MFA,但如果改用通行密鑰,這類擔心的性質本身就會改變。保護的對象從「秘密值」變成「裝置的持有」,這種感覺,是實際用過之後才真正能體會的。
密碼完全消失,應該還需要一段時間。即便如此,如果不是把它理解成「不用記密碼」的便利功能,而是把它看成「不把秘密放在任何地方」的設計思維轉換,那麼你對通行密鑰的理解應該會更進一步。