身份認證的盡頭竟然是無密碼 ?

概述

幾乎所有的系統都會面臨安全認證相關的問題,但是安全相關的問題是一個很麻煩的事情。因爲它不產生直接的業務價值,而且處理起來複雜繁瑣,所以很多時都容易被忽視。很多後期造成重大的安全隱患,往往都是前期的不重視造成的。但慶幸的是安全問題是普遍存在的,而且大家面臨的問題幾乎相同,所以可以制定行業標準來規範處理,甚至是可以抽出專門的基礎設施(例如:AD、LDAP 等)來專門解決這類共性的問題。總之,關於安全問題非常複雜而且麻煩,對於大多數 99% 的系統來說,不要想着在安全問題領域上搞發明和創新,容易踩坑。而且行業的標準解決方案已經非常成熟了。經過長時間的檢驗。所以在安全領域,踏踏實實的遵循規範和標準就是最好的安全設計。

HTTP 認證

HTTP 認證協議的最初是在 HTTP/1.1標準中定義的,後續由 IETF 在 RFC 7235 中進行完善。HTTP 協議的主要涉及兩種的認證機制。

HTTP 认证的对话框

基本認證

常見的叫法是 HTTP Basic,是一種對於安全性不高,以演示爲目的的簡單的認證機制(例如你家路由器的登錄界面),客戶端用戶名和密碼進行 Base64 編碼(注意是編碼,不是加密)後,放入 HTTP 請求的頭中。服務器在接收到請求後,解碼這個字段來驗證用戶的身份。示例:

GET /some-protected-resource HTTP/1.1
Host: example.com
Authorization: Basic dXNlcjpwYXNzd29yZA==

雖然這種方式簡單,但並不安全,因爲 base64 編碼很容易被解碼。建議僅在 HTTPS 協議下使用,以確保安全性。

摘要認證

主要是爲了解決 HTTP Basic 的安全問題,但是相對也更復雜一些,摘要認證使用 MD5 哈希函數對用戶的密碼進行加密,並結合一些鹽值(可選)生成一個摘要值,然後將這個值放入請求頭中。即使在傳輸過程中被截獲,攻擊者也無法直接從摘要中還原出用戶的密碼。示例:

GET /dir/index.html HTTP/1.1
Host: example.com
Authorization: Digest username="user", realm="example.com", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", uri="/dir/index.html", qop=auth, nc=00000001, cnonce="0a4f113b", response="6629fae49393a05397450978507c4ef1", opaque="5ccc069c403ebaf9f0171e9517f40e41"

補充:另在 RFC 7235 規範中還定義當用戶沒有認證訪問服務資源時應返回 401 Unauthorized 狀態碼,示例:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Restricted Area"

這一規範目前應用在所有的身份認證流程中,並且沿用至今。

Web 認證

表單認證

雖然 HTTP 有標準的認證協議,但目前實際場景中大多應用都還是基於表單認證實現,具體步驟是:

  1. 前端通過表單收集用戶的賬號和密碼
  2. 通過協商的方式發送服務端進行驗證的方式。

常見的表單認證頁面通常如下:

<!DOCTYPE html>
<html>
<head>
    <title>Login Page</title>
</head>
<body>
    <h2>Login Form</h2>
    <form action="/perform_login" method="post">
        <div class="container">
            <label for="username"><b>Username</b></label>
            <input type="text" placeholder="Enter Username" name="username" required>
            
            <label for="password"><b>Password</b></label>
            <input type="password" placeholder="Enter Password" name="password" required>
            
            <button type="submit">Login</button>
        </div>
    </form>
</body>
</html>

爲什麼表單認證會成爲主流 ?主要有以下幾點原因:

  • 界面美化:開發者可以創建定製化的登錄界面,可以與應用的整體設計風格保持一致。而 HTTP 認證通常會彈出一個很醜的模態對話框讓用戶輸入憑證。
  • 靈活性:可以在表單裏面自定義更多的邏輯和流程,比如多因素認證、密碼重置、記住我功能等。這些功能對於提高應用的安全性和便利性非常重要。
  • 安全性:表單認證可以更容易地結合現代的安全實踐,背後也有 OAuth 2 、Spring Security 等框架的主持。

表單認證傳輸內容和格式基本都是自定義本沒啥規範可言。但是在 2019 年之後 web 認證開始發佈標準的認證協議。

WebAuthn

WebAuthn 是一種徹底拋棄傳統密碼的認證,完全基於生物識別技術和實體密鑰作爲身份識別的憑證(有興趣的小夥伴可以在 github 開啓 Webauhtn 的 2FA 認證體驗一下)。在 2019 年 3 月,W3C 正式發佈了 WebAuthn 的第一版規範。

webauthn registration

相比於傳統的密碼,WebAuthn 具有以下優勢:

  1. 減少密碼泄露:傳統的用戶名和密碼登錄容易受到釣魚攻擊和數據泄露的影響。WebAuthn,不依賴於密碼,不存在密碼丟失風險。
  2. 提高用戶體驗:用戶不需要記住複雜的密碼,通過使用生物識別等方式可以更快捷、更方便地登錄。
  3. 多因素認證:WebAuthn 可以作爲多因素認證過程中的一部分,進一步增強安全性。使用生物識別加上硬件密鑰的方式進行認證,比短信驗證碼更安全。

總的來說,WebAuthn 是未來的身份認證方式,通過提供一個更安全、更方便的認證方式,目的是替代傳統的基於密碼的登錄方法,從而解決了網絡安全中的一些長期問題。WebAuthn 目前已經得到流程的瀏覽器廠商(Chrome、Firefox、Edge、Safari)、操作系統(WIndows、macOS、Linux)的廣泛支持。

實現效果

當你的應用接入 WebAuthn 後,用戶便可以通過生物識別設備進行認證,效果如下:

WebAuthn login

實現原理

WebAuthn 實現較爲複雜,這裏不做詳細描述,具體可參看權威的官方文檔,大概交互過程可以參考以下時序圖:

webauthn 交互时序图

登錄流程大致可以分爲以下步驟:

  1. 用戶訪問登錄頁面,填入用戶名後即可點擊登錄按鈕。
  2. 服務器返回隨機字符串 Challenge、用戶 UserID。
  3. 瀏覽器將 Challenge 和 UserID 轉發給驗證器。
  4. 驗證器提示用戶進行認證操作。
  5. 服務端接收到瀏覽器轉發來的被私鑰加密的 Challenge,以此前註冊時存儲的公鑰進行解密,如果解密成功則宣告登錄成功。

WebAuthn 採用非對稱加密的公鑰、私鑰替代傳統的密碼,這是非常理想的認證方案,私鑰是保密的,只有驗證器需要知道它,連用戶本人都不需要知道,也就沒有人爲泄漏的可能;

備註:你可以通過訪問 webauthn.me 瞭解到更多消息的信息

因爲公衆號文章不適合加入過多的演示代碼,想要手上體驗的可以參考 okta 官方給出基於 Java 17 和 Maven 構建的 webauthn 示例程序,如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章