
WebAuthn là gì: chuẩn xác thực công khai thay thế mật khẩu
WebAuthn là chuẩn W3C và FIDO cho việc xác thực bằng public key thay vì mật khẩu, được hỗ trợ rộng rãi trên trình duyệt hiện đại và hệ điều hành bao gồm Chrome, Safari, Firefox, Android, iOS, macOS và Windows. Thay vì lưu trữ mật khẩu trên máy chủ, WebAuthn tạo ra một cặp khóa công khai và bí mật ngay trên thiết bị người dùng, gửi khóa công khai cho máy chủ còn khóa bí mật thì không bao giờ rời khỏi thiết bị. Chính đặc điểm này giúp WebAuthn chống lại cả hai kiểu tấn công phổ biến nhất với mật khẩu: trộm cơ sở dữ liệu và trang web giả mạo.
FIDO2 là tổng hợp của hai thành phần chính: WebAuthn, là API JavaScript chạy trong trình duyệt, và CTAP2, là giao thức giữa trình duyệt hoặc hệ điều hành với thiết bị xác thực. Mục tiêu chung của cả hai là loại bỏ mật khẩu bằng phương thức dựa trên thiết bị bảo mật như vân tay, nhận diện khuôn mặt hoặc mã PIN, và những thông tin đăng nhập dạng này được gọi chung là passkey. Theo khảo sát của FIDO Alliance năm 2024, 53% người dùng đã bật passkey trên ít nhất một tài khoản.

Hai bước cốt lõi: đăng ký và xác thực
WebAuthn gồm hai hoạt động riêng biệt mà máy chủ phải triển khai đầy đủ:
- Đăng ký (registration) — người dùng tạo một public key credential mới rồi liên kết nó với tài khoản của mình.
- Xác thực (authentication) — người dùng chứng minh mình là chủ sở hữu của một credential đã đăng ký từ trước đó.
Cả hai bước đều bắt đầu giống nhau: máy chủ sinh ra một chuỗi thách thức ngẫu nhiên rồi gửi sang thiết bị. Thiết bị ký chuỗi đó bằng khóa bí mật và trả lại chữ ký số kèm khóa công khai. Máy chủ dùng khóa công khai đã lưu để kiểm tra chữ ký, và nếu khớp thì xác nhận đây đúng là thiết bị đã đăng ký. Vì khóa bí mật chỉ nằm trong phần cứng của thiết bị và không thể sao chép ra ngoài, WebAuthn tự nhiên chống lại tấn công giả mạo: credential bị ràng buộc với đúng tên miền mà người dùng đang truy cập, nên một trang lừa đảo không thể lấy được credential của trang thật.
Các thành phần trong hệ thống WebAuthn
| Thành phần | Vai trò |
|---|---|
| Relying Party | Ứng dụng web hoặc dịch vụ muốn xác thực người dùng, chịu trách nhiệm lưu khóa công khai. |
| Authenticator | Thiết bị lưu khóa bí mật và thực hiện phép toán mật mã, có thể tích hợp trong hệ điều hành hoặc là thiết bị rời kết nối qua USB, NFC, Bluetooth. |
| Public key credential | Cặp khóa được tạo ra trong authenticator, phần công khai được gửi lên và lưu trong cơ sở dữ liệu của máy chủ. |
| Client | Trình duyệt hoặc môi trường chạy JavaScript, đóng vai trò trung gian kết nối máy chủ với authenticator. |
Authenticator chia làm hai loại chính. Loại thứ nhất là platform authenticator, được tích hợp sâu vào hệ điều hành, ví dụ Touch ID trên macOS, Windows Hello trên máy tính, hoặc cảm biến vân tay trên điện thoại. Loại thứ hai là roaming authenticator, tức thiết bị rời bạn mang theo như chiếc khoá bảo mật, chẳng hạn YubiKey của Yubico hoặc Titan Security Key của Google. Mỗi lần đăng nhập, bạn chỉ cần chạm thiết bị hoặc quét vân tay, phần còn lại do máy thực hiện.

Tiêu chuẩn mở và mức độ hỗ trợ
WebAuthn là tiêu chuẩn mở do W3C duy trì, bản đầu tiên được công bố như một W3C Recommendation ngày 4 tháng 3 năm 2019. Phiên bản mới nhất, WebAuthn Level 3, đã đạt chuẩn ngày 25 tháng 8 năm 2026 và mở rộng phạm vi để hỗ trợ credential đa thiết bị, tức những passkey được đồng bộ giữa nhiều máy thông qua dịch vụ của hệ điều hành như iCloud Keychain hay Google Password Manager.
Trên phía client, mọi trình duyệt từ Chrome 67, Firefox 60, Safari 13 và Edge 18 trở lên đều hỗ trợ WebAuthn. Chuẩn này yêu cầu bối cảnh bảo mật, tức phải chạy qua HTTPS, vì các thao tác trong đó là thao tác mật mã nhạy cảm. Trên phía máy chủ, bất kỳ ngôn ngữ lập trình nào có thể gửi và nhận JSON qua HTTP đều có thể triển khai WebAuthn bằng các thư viện có sẵn như pywebauthn cho Python, webauthn4j cho Java, hoặc thư viện chính thức của dự án WebAuthn cho Go.
Tài liệu đặc tả hiện tại nằm ở w3.org/TR/webauthn-3, phần giới thiệu dành cho người mới bắt đầu có sẵn tại webauthn.io. Trang tổng hợp về passkey của FIDO Alliance nằm ở fidoalliance.org/passkeys, danh sách đặc tả FIDO đầy đủ ở fidoalliance.org/specifications, và bảng hỗ trợ trình duyệt được cập nhật thường xuyên tại caniuse.com/webauthn. Nếu bạn muốn hiểu sâu hơn về cơ chế bên trong, hướng dẫn từng bước của cộng đồng nằm tại webauthn.guide.

Tại sao WebAuthn an toàn hơn mật khẩu?
- Không có bí mật trên máy chủ. Máy chủ chỉ lưu khóa công khai. Ngay cả khi cơ sở dữ liệu bị rò rỉ toàn bộ, kẻ tấn công cũng không thể tạo ra khóa bí mật tương ứng để đăng nhập.
- Chống giả mạo hiệu quả. Credential gắn với đúng tên miền đang truy cập, nên một trang lừa đảo có tên gần giống cũng không lấy được credential của trang thật.
- Chống phát lại tín hiệu. Mỗi lần đăng nhập đều đi kèm một chuỗi thách thức mới sinh từ máy chủ, nên tín hiệu đã ghi lại từ trước không dùng lại được.
- Không có bí mật dùng chung. Khác với mã một lúc dựa trên khóa bí mật chung, mỗi credential là duy nhất cho từng tài khoản nên không thể rò rỉ theo dây chuyền.
Dù an toàn hơn, WebAuthn vẫn có vài điểm cần chú ý khi triển khai. Trước hết, thông tin tài khoản có tồn tại hay không vẫn là dữ liệu hữu ích cho kẻ tấn công, nên máy chủ phải luôn trả về cùng một phản hồi bất kể tên người dùng có tồn tại hay không. Thứ hai, chênh lệch thời gian phản hồi cũng có thể làm lộ thông tin, vì vậy nên thực hiện phép toán xác minh ngay cả khi tên người dùng không tồn tại. Cuối cùng, nếu chỉ hỗ trợ passkey trên thiết bị đa phương tiện thì người dùng có thể mất quyền truy cập khi xóa tài khoản đồng bộ, nên vẫn nên giữ phương án dự phòng bằng khóa bảo mật vật lý.
Lỗi thường gặp khi triển khai WebAuthn
- Quên bật HTTPS. WebAuthn yêu cầu bối cảnh bảo mật, nên mọi lần đăng ký trên giao thức http đều thất bại ngay lập tức.
- Tái sử dụng chuỗi thách thức. Nếu máy chủ dùng lại cùng một chuỗi cho nhiều phiên, kẻ tấn công có thể ghi lại phản hồi rồi phát lại sau đó.
- Không kiểm tra origin. Thư viện phía client tự kiểm tra, nhưng nếu bạn tự viết JavaScript thì phần này thuộc về trách nhiệm của bạn.
- Trường lưu khóa công khai quá hẹp. Khóa công khai là cấu trúc nhị phân có chiều dài biến động, nên cần cột BLOB hoặc văn bản đủ lớn thay vì chuỗi cố định ngắn.
- Sai kiểu dữ liệu khi đọc phản hồi. Một số thư viện phía máy chủ mong nhận danh sách credential, trong khi API JavaScript gửi từng credential một.
Với hơn một nửa người dùng đã bật passkey trên ít nhất một tài khoản, xu hướng thay mật khẩu bằng WebAuthn và FIDO2 chỉ đang bắt đầu. Các nhà cung cấp lớn như Google, Apple và Microsoft đã tích hợp sẵn chức năng này vào hệ sinh thái của họ, và trong các năm tới việc tạo tài khoản mới sẽ mặc định là dùng passkey thay vì điền biểu mẫu mật khẩu.
