Vì sao passkey an toàn ── hình giải cơ chế "xác thực không gửi bí mật"

· Cập nhật ngày: · · Passkey, WebAuthn, FIDO2, Bảo mật, Xác thực, Chống phishing, Hệ thống thông tin

Tin “lại một dịch vụ lớn để lộ mật khẩu” chẳng còn ai ngạc nhiên. Huấn luyện phishing hàng năm, số người mắc vẫn không về không. “Đừng dùng lại mật khẩu, hãy làm dài, đổi định kỳ… thôi không cần nữa” ── lời khuyên cũng đảo đi đảo lại.

Passkey, lan nhanh vài năm gần đây, là cách xác thực Apple, Google và Microsoft cùng thúc đẩy như câu trả lời cho tình hình này.1 Hay được giới thiệu là “tiện, đăng nhập bằng vân tay hay khuôn mặt” ── nhưng bản chất không nằm đó. Giá trị thật của passkey là chuyển căn cứ an toàn từ “sự chú ý của con người” sang “cấu trúc của giao thức”.

  • Mật khẩu lộ vì người dùng bất cẩn, nên hãy giáo dục → con người chắc chắn sai
  • Hãy huấn luyện nhận ra site giả → làm được site giả nhìn không ra
  • Passkey thì → vốn không có bí mật để gửi, và trên site giả chữ ký không thành

Bài viết này, xuất phát từ mật khẩu đang hỏng chỗ nào, nắm bằng hình vì sao passkey an toàn. Rồi trả lời thẳng các nghi ngờ đương nhiên ── “passkey đồng bộ có thật sự an toàn?”, “có điểm yếu không?” ── và cuối cùng sắp xếp các điểm then chốt khi đưa vào ứng dụng web và môi trường Windows.

1. Kết luận trước

Lý do passkey an toàn gom thành ba điểm.

  1. Máy chủ không có bí mật. Máy chủ chỉ lưu khóa công khai, thông tin lộ cũng không lợi dụng được. Cơ sở dữ liệu tuột cả cụm, kẻ tấn công cũng không mang về được “nguyên liệu mạo danh”.2
  2. Bí mật không đi trên mạng. Lúc đăng nhập chỉ gửi chữ ký trên số ngẫu nhiên dùng một lần (challenge). Khóa riêng không rời authenticator của thiết bị, nên nghe lén hay chuyển tiếp chỗ nào trên đường cũng không lấy được bí mật.2
  3. Trên site giả chữ ký không thành. Passkey gắn với domain của site, trình duyệt buộc khớp domain. Người dùng bị lừa vào site giả, passkey của site thật vốn không hiện ứng viên, dù chuyển tiếp chữ ký thì xác minh vẫn rớt.3

Ba điểm này không phải ba mẹo độc lập ── đều là hệ quả từ một thay đổi thiết kế: chuyển từ xác thực “chia sẻ rồi gửi bí mật” sang xác thực “chứng minh đang giữ bí mật bằng chữ ký”. Lần lượt xem.

Quan hệ thuật ngữ ── passkey, WebAuthn, FIDO2, CTAP

Lĩnh vực này thuật ngữ nhiều, phạm vi mỗi bài khác nhau, nên trước hết chốt quan hệ. Passkey không phải giao thức mới ── là “tên gọi” gắn lên tổ hợp các chuẩn sẵn có.21

Thuật ngữ Tên chính thức Chỉ cái gì
WebAuthn Web Authentication API (khuyến nghị W3C) Chuẩn giữa trình duyệt và website. API dùng navigator.credentials để yêu cầu tạo cặp khóa và ký
CTAP Client to Authenticator Protocol (FIDO Alliance) Chuẩn giữa trình duyệt và authenticator gắn ngoài. Phần nói chuyện với security key hay điện thoại qua USB, NFC, Bluetooth
FIDO2 Tên chung khung gồm hai thứ trên. FIDO2 = WebAuthn + CTAP
Passkey Tên gọi tập con thông tin xác thực FIDO2 cho phép đăng nhập đơn độc thay mật khẩu (discoverable credential)

Bảng 1: Passkey là tên gọi trên nền FIDO2, không phải tên chuẩn

Tức “hỗ trợ passkey” nói bằng lời triển khai là “triển khai WebAuthn”. CTAP là lớp trình duyệt và OS lo hộ khi dùng authenticator gắn ngoài, nên phía làm ứng dụng web không đụng trực tiếp.

Bản đồ tri thức của bài viết này

Passkey là thông tin xác thực dựa mật mã khóa công khai, đứng trên các chuẩn WebAuthn và CTAP (gộp thành FIDO2); khóa riêng không rời authenticator, máy chủ chỉ nhận khóa công khai lộ cũng không lợi dụng được. Passkey được tạo gắn với domain của site (RP ID), nên trên site giả chữ ký vốn không thành và phishing bị ngăn về cấu trúc. Passkey đồng bộ đổi lấy phụ thuộc tài khoản đám mây để chịu mất máy, còn kiểu gắn thiết bị nhốt khóa trong phần cứng. Sau khi đưa passkey vào, thực tế tập trung vào thu hẹp phương tiện dự phòng song song và tăng cường luồng khôi phục tài khoản.

Bản đồ tri thức vì sao passkey an toànSơ đồ cho thấy passkey đứng trên WebAuthn, FIDO2, CTAP, mật mã khóa công khai; gắn domain bằng RP ID ngăn phishing về cấu trúc; khác biệt kiểu đồng bộ và gắn thiết bị cùng điểm lỗi đơn từng bên; vị trí như MFA kháng phishing; quan hệ rủi ro còn lại (dự phòng, khôi phục tài khoản, đánh cắp phiên)sử dụngsử dụngsử dụngsử dụngsử dụngsử dụngsử dụngsử dụngsử dụngsử dụngsử dụngyêu cầusử dụngyêu cầungăn chặnngăn chặnngăn chặngiảm thiểucó thể gâycó thể gâycó thể gâycó thể gâycó thể gâykhông khuyến nghịkhuyến nghị chosử dụngcấu hình bằnglưu trongkhông tương thíchkhuyến nghị chocó thể gâykhuyến nghị chocó thể gâykhuyến nghị chocó thể gâykhuyến nghị chocó thể gâykhông khuyến nghịPasskeyWebAuthnFIDO2Mật mã khóa công khaiCTAPAuthenticatorTPMWindows HelloSecurity keyPasskey gắn thiết bịYêu cầu secure context (HTTPS)Challenge (số ngẫu nhiên dùng một lần)RP ID (định danh Relying Party)Lừa đảo (phishing)Phishing kiểu AiTM (trung gian)Lộ cơ sở dữ liệu thông tin xác thựcXác thực mật khẩuDùng lại mật khẩu (tấn công danh sách)Chiếm tài khoảnĐánh cắp cookie phiênMã một lần (TOTP)MFA kháng phishingMicrosoft Entra IDPasskey đồng bộKho thông tin xác thực của nền tảngNIST AAL3 (mức bảo đảm authenticator 3)Tăng cường bảo vệ tài khoản nền tảngLợi dụng luồng khôi phục tài khoảnTăng cường xác minh danh tính luồng khôi phụcPhương tiện xác thực dự phòng song songThu hẹp có kế hoạch các phương tiện dự phòng

Trong sơ đồ, đường liền nét biểu thị quan hệ luôn đúng và đường nét đứt biểu thị quan hệ có điều kiện (điều kiện nằm trong phần giải thích từng quan hệ trên trang chi tiết). Danh sách đầy đủ các quan hệ (tổng 38, kèm bằng chứng và mức chắc chắn) cùng định nghĩa các khái niệm chính được tập hợp tại trang chi tiết bản đồ tri thức (bằng tiếng Nhật). Dữ liệu: JSON-LD / Turtle

2. Xác thực mật khẩu đang hỏng chỗ nào

Lối tắt hiểu vì sao passkey an toàn là nắm điểm yếu mật khẩu theo “chỗ”. Với xác thực mật khẩu, bản thân bí mật đi suốt mọi đoạn mỗi lần xác thực.

Máy chủTrình duyệtNgười dùngMáy chủTrình duyệtNgười dùngGiữ bí mật (mật khẩu) trong đầu[Điểm yếu 1] Đoán được, dùng lại nhiều site[Điểm yếu 2] Site giả cũng nhập đượcy như vậy (nhìn không phân biệt)[Điểm yếu 3] Bí mật đi trên đườngTLS bảo vệ nhưng đầu cuối lại thành plaintext[Điểm yếu 4] Bí mật (hash) mọi người dùng tụ lạiLộ thì thành đích vét cạn offlineNhập mật khẩuGửi chính mật khẩuĐối chiếu với hash đã lưu

Hình 1: Với xác thực mật khẩu, bản thân bí mật tồn tại trên toàn đoạn

Từ phía kẻ tấn công, đây là cấu trúc nhiều đích, dễ bắn.

  • Điểm yếu 1 (người dùng): chỉ mạnh đến mức nhớ được, hay dùng lại nhiều site. Một chỗ lộ lan mọi tài khoản (tấn công danh sách mật khẩu).
  • Điểm yếu 2 (lúc nhập): chuẩn bị site giả nhìn không ra thật, người dùng tự đưa bí mật (phishing).
  • Điểm yếu 3 (đường truyền): có TLS nên nghe lén chính đường khó, nhưng bị kẹp “điểm chuyển tiếp trông hợp lệ” thì vô nghĩa (AiTM nói sau).
  • Điểm yếu 4 (máy chủ): dù hash rồi lưu, cơ sở dữ liệu lộ thì vét cạn offline. Mật khẩu yếu vỡ trước.

“Vậy thêm mã một lần (SMS hay TOTP)?” là xác thực đa yếu tố cũ, nhưng cấu trúc gửi bí mật dùng chung không đổi. TOTP thì máy chủ và ứng dụng xác thực chia sẻ cùng seed (bí mật), mã 6 chữ số sinh ra rốt cuộc người dùng vẫn nhập vào site giả được. Thực tế, phishing kiểu AiTM (Adversary-in-the-Middle) mà site giả chuyển tiếp thời gian thực sang máy chủ thật, tuồn nguyên bộ mật khẩu + mã một lần để vượt. CISA (cơ quan an ninh mạng Mỹ) liệt kê “MFA kháng phishing” chỉ hai: cách FIDO/WebAuthn, và xác thực dựa PKI như thẻ thông minh (PIV/CAC); trong đó đặt FIDO làm gold standard, chính vì vậy.4

Tức vấn đề không phải “độ mạnh” mật khẩu, mà chính cấu trúc “chia sẻ bí mật rồi gửi mỗi lần xác thực”.

3. Passkey là gì ── không gửi bí mật, chứng minh đang giữ

Passkey là thông tin xác thực dựa mật mã khóa công khai, đứng trên hai chuẩn WebAuthn của W3C và CTAP của FIDO Alliance (gộp thành FIDO2).21 Nghe khó, cấu trúc thì đơn giản.

Máy chủThiết bị người dùngđối chiếu cục bộcặp toán học(phía tạo chữ ký)Khóa công khailộ cũng không lợi dụng đượcthông tin 'chỉ để xác minh'Authenticator (két)Windows Hello / Face ID /khóa màn hình Android / security keyKhóa riêngkhông rời chỗ nàyVân tay, khuôn mặt, PIN= chỉ mở cửa kétcái này cũng không ra ngoài

Hình 2: Thực thể passkey là cặp khóa theo từng site. Phía bí mật không rời thiết bị; máy chủ chỉ giữ khóa công khai để xác minh

  • Khóa riêng là khóa phía tạo được chữ ký, lưu trong authenticator trên thiết bị (Windows Hello, Face ID/Touch ID trên iPhone, khóa màn hình Android, hoặc security key kiểu YubiKey) và không ra ngoài.
  • Khóa công khai là khóa phía chỉ xác minh chữ ký, gửi cho máy chủ. Tính ngược khóa riêng từ khóa công khai về mặt tính toán là không khả thi, nên lộ cũng không sao.
  • Thông tin sinh trắc vân tay, khuôn mặt chỉ dùng để mở cửa két cục bộ, cũng không rời thiết bị. Máy chủ không nhận thông tin sinh trắc.1

Đăng ký: chỉ đưa khóa công khai

Luồng lúc đăng ký passkey với site.

AuthenticatorTrình duyệtMáy chủ (example.com)AuthenticatorTrình duyệtMáy chủ (example.com)Máy chủ nhận được chỉ"thông tin lộ cũng không lợi dụng được"Yêu cầu đăng ký (challenge ngẫu nhiên + thông tin site)Tạo khóa cho site này (example.com)Xác minh danh tính bằng vân tay, khuôn mặt, PIN (cục bộ)Sinh cặp khóa mớikhóa riêng cất bên trongKhóa công khai + credential ID (nhãn khóa)Gửi khóa công khai + credential IDLưu như khóa công khai của tài khoản này

Hình 3: Lúc đăng ký, thứ đi trên mạng và lưu trên máy chủ chỉ là khóa công khai

Điểm quan trọng: lúc này cặp khóa được tạo gắn với domain của site (RP ID). Passkey tạo cho example.com chỉ dùng trên site example.com (RP ID theo đơn vị domain nên trang subdomain cùng domain như login.example.com dùng được, nhưng domain không liên quan thì không). Gắn kết này là nền kháng phishing nói sau.3

Thêm nữa, cặp khóa được tạo mới mỗi site. Passkey site A và site B không liên quan toán học, nên khái niệm “dùng lại” vốn không tồn tại, cũng không thành nguyên liệu đối chiếu người dùng giữa các site.

Xác thực: trả chữ ký dùng một lần

Luồng lúc đăng nhập. So với xác thực mật khẩu (Hình 1).

AuthenticatorTrình duyệtMáy chủ (example.com)AuthenticatorTrình duyệtMáy chủ (example.com)Trên đường chỉ đi chữ ký dùng một lầnăn cắp cũng không dùng cho challenge lần sauYêu cầu đăng nhập (challenge ngẫu nhiên dùng một lần)Yêu cầu chữ ký cho example.comXác minh danh tính bằng vân tay, khuôn mặt, PIN (cục bộ)Tạo chữ ký bằng khóa riêngnhúng challenge + origin + hash RP IDChữ ký (không phải bản thân khóa riêng)Gửi chữ kýXác minh chữ ký bằng khóa công khai đã lưucũng kiểm challenge, origin, RP ID

Hình 4: Lúc xác thực bí mật cũng không di chuyển. Thứ chảy chỉ là “giấy chứng minh dùng một lần”

Máy chủ mỗi lần ra số ngẫu nhiên mới (challenge); authenticator ký trên “challenge đó + origin trình duyệt đang thấy + hash RP ID”. Máy chủ xác minh chữ ký bằng khóa công khai đã lưu, xác nhận challenge là đề mình ra, origin và RP ID là của site mình.5

Hệ quả thiết kế này, hai trong ba lý do đầu bài đã thành.

  • Máy chủ không có bí mật: chỉ lưu khóa công khai. Lộ thì kẻ tấn công không tạo được chữ ký, nên không “mang về bẻ” như hash mật khẩu.
  • Bí mật không chảy: ăn cắp chữ ký trên đường, challenge dùng một lần nên không tái sử dụng (replay).

Còn một, “trên site giả chữ ký không thành”, là điểm bán lớn nhất của passkey. Tách mục xem.

4. Lý do phishing “về cấu trúc” không thành

Phishing với mật khẩu thành vì nhập được bí mật thật vào site giả. Người ta (nhất là lúc mệt) không phân example.comexamp1e.com, nhưng ô nhập mật khẩu trên site nào cũng chạy giống nhau.

Với passkey, việc khớp này trình duyệt làm máy móc, không phải con người. Theo đặc tả WebAuthn, trình duyệt chỉ gọi authenticator khi domain của origin đang hiển thị tương ứng với RP ID của passkey.3 Vào site giả thì chuyện gì xảy ra, vẽ như sau.

Máy chủ thật (example.com)Site giả (examp1e.com)proxy AiTM chuyển tiếp sang thậtTrình duyệtNgười dùngMáy chủ thật (example.com)Site giả (examp1e.com)proxy AiTM chuyển tiếp sang thậtTrình duyệtNgười dùngDù bằng cách nào đó chữ ký được tạo,chữ ký nhúng examp1e.com nênxác minh phía máy chủ thật chắc chắn rớtVào màn hình đăng nhập trông y hệt(ngầm) bắt đầu xử lý đăng nhập thậtChallengeTuồn challenge, yêu cầu chữ kýOrigin hiện tại là examp1e.comkhông đưa được passkey của example.com làm ứng viênChữ ký không được tạo (người dùng không thể bị lừa)

Hình 5: Phishing kiểu AiTM vượt mật khẩu + mã một lần, nhưng với passkey thì không thành ở bước chữ ký

Chú ý phòng thủ hai lớp.

  1. Không hiện ứng viên: trình duyệt chỉ liệt kê passkey có RP ID tương ứng origin. Trên domain giả, passkey của site thật không hiện lựa chọn, nên người dùng “lỡ dùng” cũng không được.
  2. Chữ ký không qua: đối tượng ký gồm origin trình duyệt đã xác nhận và hash RP ID. Máy chủ thật khớp lúc xác minh, chữ ký tạo ở origin khác chắc chắn bị từ chối.5

Chống phishing mật khẩu phụ thuộc nỗ lực con người “nhìn kỹ URL”. Với passkey, người dùng vốn không cần nhận ra site giả. Đó là nghĩa đúng của “kháng phishing (phishing-resistant)”, và lý do CISA cùng NIST (Viện Tiêu chuẩn và Công nghệ Quốc gia Mỹ) đối xử đặc biệt cách FIDO/WebAuthn.46

Nội dung đến đây, sắp theo từng kiểu tấn công.

Tấn công Mật khẩu Mật khẩu + TOTP Passkey
Đoán, vét cạn ✗ yếu △ mã chặn được nhưng mật khẩu gốc vẫn yếu ○ không có đối tượng đoán
Dùng lại (tấn công danh sách) ✗ một chỗ lộ lan cả △ sụp từ site chưa hỗ trợ mã ○ khóa độc lập từng site
Lộ DB máy chủ ✗ vét cạn hash offline ✗ seed TOTP (bí mật dùng chung) cũng lộ ○ chỉ có khóa công khai
Phishing cổ điển (bắt nhập trên site giả) ✗ nhập được ✗ mã cũng nhập được ○ không hiện ứng viên, chữ ký cũng không qua
AiTM (chuyển tiếp thời gian thực) ✗ tuồn nguyên ✗ tuồn cả mã ○ khớp origin thì chữ ký không thành
Replay (tái sử dụng giao tiếp) ✗ cùng mật khẩu dùng nhiều lần △ mã cướp trước khi chủ dùng thì còn hiệu (tái nhận mã đã dùng, triển khai đúng thì từ chối) ○ challenge mỗi lần dùng một lần

Bảng 2: So sánh kháng theo kiểu tấn công. Mọi “○” của passkey đều từ cấu trúc, không từ vận hành hay chú ý

5. “Passkey đồng bộ” có an toàn không

Đọc đến đây, nghi ngờ đương nhiên nổi: “nói khóa riêng không rời thiết bị, sao passkey tạo trên iPhone dùng được trên iPad?” ── câu hỏi hay; trả lời là “passkey có hai loại”.

Trước hết bảng xem nhanh. Mục này và mục sau giải thích vì sao từng hàng bảng lại như vậy.

Góc nhìn Passkey đồng bộ Passkey gắn thiết bị
Ví dụ điển hình iCloud Keychain, Google Password Manager, trình quản lý mật khẩu như 1Password Security key (YubiKey, v.v.), Windows Hello, passkey trong Microsoft Authenticator
Chỗ giữ khóa riêng Kho thông tin xác thực của nền tảng. Nhân bản dạng mã hóa đầu cuối giữa thiết bị cùng tài khoản Trong phần cứng authenticator. Không ra ngoài TPM hay secure element
Lúc mất, đổi máy Đăng nhập cùng Apple ID/tài khoản Google thì khôi phục được sang máy mới Passkey của authenticator đó mất. Tiền đề là đăng ký nhiều authenticator dự phòng
Điểm lỗi đơn Tài khoản đám mây của nền tảng Bản thân thiết bị vật lý
Hợp quản lý doanh nghiệp Khóa vào tài khoản đám mây cá nhân, phía tổ chức khó nắm chỗ và thu hồi hàng loạt. Hợp BYOD, quy mô nhỏ Quản trị viên phát và thu hồi được, chỗ khóa rõ. Hợp môi trường quy định chặt
Phù hợp AAL của NIST Thỏa yêu cầu thì AAL2. Khóa riêng xuất được nên không dùng cho AAL36 Authenticator bảo vệ bằng phần cứng, không lấy khóa ra được, có thể đáp yêu cầu AAL3 đòi6

Bảng 3: Bảng xem nhanh kiểu đồng bộ và gắn thiết bị. Chọn bên nào quyết theo lấy “mạnh trước mất máy” hay “quản được chỗ khóa”

Passkey gắn thiết bịSecurity key (YubiKey, v.v.) /Windows Hello /Microsoft Authenticator (Entra ID)Khóa riêng không rời phần cứng đóvề vật lý (bảo vệ bằng TPM, v.v.)Lợi: chỗ khóa rõ, một nơiLưu ý: phải đăng ký nhiều để phòng mấtPasskey đồng bộ (mặc định hướng người tiêu dùng)iCloud Keychain /Google Password Manager /trình quản lý mật khẩu như 1PasswordĐồng bộ mã hóa đầu cuối giữathiết bị cùng tài khoảnnhà cung cấp cũng không đọc được nội dungLợi: mạnh trước đổi máy, mất máyLưu ý: cần phòng thủ chính tài khoản đám mây

Hình 6: Kiểu đồng bộ và gắn thiết bị. Cả hai cùng “không gửi khóa riêng lên máy chủ”; trọng tâm cách giữ khác nhau

Passkey đồng bộ là kiểu iCloud Keychain hay Google Password Manager đồng bộ khóa riêng giữa thiết bị cùng tài khoản. Điểm then chốt: đồng bộ mã hóa đầu cuối. Cả Apple lẫn Google nói rõ passkey được mã hóa trên thiết bị rồi mới đồng bộ, chính nhà cung cấp cũng không đọc được nội dung.78 Tức nguyên tắc “khóa riêng không rời thiết bị” được nới chính xác thành “khóa riêng không rời thiết bị dưới dạng plaintext”, đổi lấy sức chịu đổi máy và mất máy.

Cần nói rõ nới này đổi mô hình đe dọa thế nào. Chỗ phải giữ gom từ “máy chủ từng site” thành “một tài khoản đám mây”. Vẫn mạnh trước lộ DB từng site và phishing như cũ, lần này chiếm Apple ID/tài khoản Google thành điểm lỗi đơn. Vì vậy tài khoản nền tảng giữ passkey phải được bảo vệ mạnh nhất (khóa màn hình mạnh, sắp xếp phương tiện khôi phục, nếu được thì security key vật lý) là tiền đề. NIST tháng 4 năm 2024 cũng ra phụ lục NIST SP 800-63B (Supplement 1: Incorporating Syncable Authenticators Into NIST SP 800-63B), chính thức đặt passkey đồng bộ (syncable authenticator) thỏa yêu cầu thì có thể đạt AAL2 (Authenticator Assurance Level 2) theo tiêu chuẩn chính phủ. Tuy nhiên, vì khóa riêng có thể xuất, AAL3 đòi môi trường cô lập bằng phần cứng thì không dùng kiểu đồng bộ.6

Passkey gắn thiết bị là kiểu khóa riêng không rời phần cứng. Security key kiểu YubiKey là điển hình; phía doanh nghiệp, passkey Entra ID của Microsoft (tạo trong Microsoft Authenticator) cũng là kiểu gắn thiết bị.9 Windows Hello trên Windows, nếu có TPM, bảo vệ khóa riêng dưới TPM. Cơ chế “két phần cứng không đưa khóa ra ngoài” này cùng nền đã giải thích chi tiết trong bài TPM.

Ngoài ra, lúc “đăng nhập trình duyệt PC bằng passkey trên điện thoại” bị bắt quét QR, có thể thấy lạ. Đó không chỉ chuyển màn hình ── là cách lai (xác thực cross-device của FIDO) xác nhận gần vật lý giữa điện thoại và PC bằng Bluetooth. Xác nhận gần triệt tấn công kẻ từ xa bắt người khác phê đăng nhập vào PC của mình qua QR.1

6. Không phải viên đạn bạc ── điểm yếu không “biến mất” mà “dịch”

Đến đây đã giải thích sức mạnh passkey, nhưng nói thẳng, passkey không xóa tấn công mà đẩy kẻ tấn công sang chỗ yếu hơn. Khi cửa trước xác thực cứng, kẻ tấn công đi đâu, vẽ như sau.

Kẻ tấn côngBản thân xác thựcchữ ký challenge[Cứng]Luồng khôi phục tài khoảnkhai 'mất passkey' rồiđặt lại bằng SMS hay email,đăng ký passkey của kẻ tấn côngPhương tiện dự phòng song songcòn mật khẩu, đăng nhập SMSthì mắt xích yếu nhất ở đóTài khoản đám mâykiểu đồng bộ thì Apple ID /tài khoản Google là điểm lỗi đơnPhiêncắp cookie sau đăng nhậpthì cách xác thực không liên quan

Hình 7: Cửa trước (xác thực) cứng thì tấn công chuyển sang luồng khôi phục, phương tiện song song, tài khoản đám mây, phiên

Rủi ro còn lại cần nắm cho thực tế có bốn.

  1. Phương tiện dự phòng song song thành mắt xích yếu nhất. Chỉ “cũng dùng được” passkey, mật khẩu hay đăng nhập SMS còn thì kẻ tấn công dùng phía đó. Kháng phishing nhìn cả tài khoản bị phương tiện đăng nhập yếu nhất giới hạn tốc độ. Lõi đưa vào không phải thêm passkey mà thu hẹp, bãi bỏ có kế hoạch các phương tiện dự phòng.
  2. Luồng khôi phục thành mặt tấn công mới. Thủ đoạn giả “mất thiết bị” để đưa vào đặt lại qua cửa hỗ trợ hay email, đăng ký passkey của chính kẻ tấn công. Thực tế, kỹ thuật xã hội lừa help desk để né xác thực cứng đã là thủ pháp quen của xâm nhập quy mô lớn. Xác thực cứng bao nhiêu, thiết kế xác minh danh tính lúc xin khôi phục lại bị hỏi bấy nhiêu.
  3. Kiểu đồng bộ thì tài khoản đám mây là điểm lỗi đơn. Như mục trước. Cần phòng thủ tài khoản giữ passkey, và với tổ chức thì chính sách “cho đồng bộ sang nền tảng nào”.
  4. Không chặn được đánh cắp phiên. Passkey chỉ giữ khoảnh khắc đăng nhập; cookie phiên sau đăng nhập bị malware hay XSS lấy thì cách xác thực không liên quan. Việc lớp khác ── thời hạn token, binding, quản lý sức khỏe thiết bị ── vẫn còn.

Đây không phải chuyện “thôi đừng dùng passkey”. Chìa cửa trước mới nhất rồi, khóa cửa sổ vẫn là việc khác ── chuyện đương nhiên. Ngược lại chỗ yếu rõ thì dồn tài nguyên phòng thủ vào luồng khôi phục và quản lý phiên được.

7. Đưa vào thực tế ── WebAuthn API và môi trường Windows

Cuối cùng, nắm điểm then chốt từ phía đưa vào.

Gắn đăng nhập passkey vào dịch vụ web của mình

Phía trình duyệt chỉ hai hàm WebAuthn API. Đăng ký gọi navigator.credentials.create(), xác thực gọi navigator.credentials.get().

// Đăng ký (phía trình duyệt)
const credential = await navigator.credentials.create({
  publicKey: {
    challenge: challengeFromServer,   // Số ngẫu nhiên dùng một lần máy chủ sinh
    rp: { id: "example.com", name: "Example" },
    user: { id: userIdBytes, name: "taro@example.com", displayName: "Taro" },
    pubKeyCredParams: [{ type: "public-key", alg: -7 }],  // ES256
    authenticatorSelection: {
      residentKey: "required",        // Làm thành thông tin xác thực khám phá được (= passkey)
      userVerification: "required",   // Bắt xác minh danh tính bằng sinh trắc/PIN
    },
  },
});
// Khóa công khai lấy từ credential.response; credential ID lấy
// từ credential.id / credential.rawId ở cấp trên cùng. Cũng như lúc
// xác thực, xác minh challenge, origin và RP ID phía máy chủ
// trước khi lưu phản hồi đăng ký.

Ý nghĩa các tham số chính như sau.

Tham số Vai trò Lưu ý lúc triển khai
challenge Số ngẫu nhiên dùng một lần máy chủ sinh mỗi lần Dùng số ngẫu nhiên mật mã không đoán được. Phía máy chủ xác minh “là cái mình phát, chưa dùng” rồi tiêu thụ
rp.id Domain gắn thông tin xác thực (RP ID) Bỏ thì thành domain hiệu lực của origin gọi. Chỉ chỉ định trong phạm vi domain đăng ký được, kiểu từ login.example.com chỉ định example.com
user.id Định danh người dùng nội bộ máy chủ (user handle) Giá trị mờ tối đa 64 byte. Đừng nhét nguyên thông tin nhận diện cá nhân như địa chỉ email hay tên người dùng2
user.name / user.displayName Chuỗi hiện trên UI authenticator hay trình duyệt để người dùng chọn tài khoản Chỉ để hiện. Máy chủ không được tin giá trị này để xác định tài khoản
pubKeyCredParams Liệt kê thuật toán khóa công khai chấp nhận theo thứ tự ưu tiên Ghi thêm -257 (RS256) cạnh -7 (ES256) thì bề rộng authenticator nhận được rộng hơn
authenticatorSelection Tính chất đòi hỏi authenticator residentKey: "required" thành passkey (discoverable credential); userVerification: "required" bắt xác minh danh tính bằng sinh trắc/PIN

Bảng 4: Các tham số chính của navigator.credentials.create()

Lưu ý môi trường kiểm: WebAuthn API chỉ công khai trong secure context, nên trang phát bằng http:// thuần thì gọi navigator.credentials thất bại. Ngoại lệ là http://localhost (và 127.0.0.1), được coi origin đáng tin nên máy phát triển không HTTPS hóa vẫn thử được. Tuy nhiên RP ID phải là domain hiệu lực của origin (hoặc domain cha), nên passkey tạo trên localhost không dùng trên domain sản xuất. Không có authenticator trong tay, bật authenticator ảo ở thẻ “WebAuthn” của DevTools Chrome vẫn chạy được từ đăng ký đến xác thực.

// Xác thực (phía trình duyệt)
const assertion = await navigator.credentials.get({
  publicKey: {
    challenge: challengeFromServer,
    rpId: "example.com",
    userVerification: "required",
  },
  // Đưa passkey ra làm ứng viên điền tự động trong ô đăng nhập. Kiểm tra
  // hỗ trợ trước bằng PublicKeyCredential.isConditionalMediationAvailable(),
  // và trình duyệt không hỗ trợ thì lùi về gọi thường không gắn mediation.
  mediation: "conditional",
  // (Cần autocomplete="username webauthn" trên <input> đích)
});
// Xác minh chữ ký trong assertion.response phía máy chủ

Phần chính là xác minh phía máy chủ. Tối thiểu luôn làm các việc sau.5

  • Khớp challenge: có phải challenge chưa dùng do mình phát không. Có dùng một lần không (chống replay). Thêm nữa, lưu gắn với phiên trình duyệt (lần thử đăng nhập) lúc phát, chỉ cho tiêu thụ từ phản hồi cùng phiên. Chỗ này lỏng thì sinh lỗ kẻ tấn công đẩy chữ ký trên challenge gửi cho mình qua trình duyệt nạn nhân, bắt nạn nhân đăng nhập vào tài khoản kẻ tấn công (login CSRF).
  • Khớp origin: origin trong clientDataJSON có phải origin chính thức của site mình không (then chốt chống phishing).
  • Khớp hash RP ID: rpIdHash trong authenticatorData có khớp SHA-256 của RP ID site mình không.
  • Xác nhận loại ceremony và cờ: type trong clientDataJSON lúc xác thực là webauthn.get, lúc đăng ký là webauthn.create chưa. Cờ UP (user present) trong authenticatorData đã bật chưa. Nếu đòi user verification (UV) thì cờ UV cũng bật chưa.
  • Xác minh chữ ký: chữ ký xác minh đúng bằng khóa công khai lưu lúc đăng ký chưa.
  • Gắn với tài khoản: tra credential ID (và userHandle) đã trình trong cơ sở dữ liệu mình, rồi phát phiên cho đúng chủ thông tin xác thực đó. Tin vô điều kiện tên người dùng nhập riêng thì thành lỗ đăng nhập người khác bằng chữ ký đúng.
  • Lưu và so sánh bộ đếm chữ ký: lưu signCount trong authenticatorData theo từng thông tin xác thực, xác nhận giá trị lần sau lớn hơn lần trước. Bằng hoặc nhỏ hơn lần trước (kể cả bằng) thì coi dấu hiệu bản sao (clone) authenticator. Tuy nhiên nhiều triển khai passkey đồng bộ luôn trả 0, nên chỉ cặp 0 với 0 hãy cho ngoại lệ.

Viết tay xác minh này dễ tai nạn, hãy dùng thư viện đã có thành tích (.NET thì fido2-net-lib, Node.js thì SimpleWebAuthn, v.v.). Chi tiết đặc tả (parse CBOR, thỏa thuận thuật toán, quản lý challenge) giao thư viện; mình tập trung lưu và hết hạn challenge, UI quản lý nhiều passkey, thiết kế luồng khôi phục ── đó mới là phân bổ sức đúng.

Môi trường Windows, hệ thống nội bộ

Với tầng độc giả site này ── “vị trí đang giữ hệ thống nghiệp vụ Windows” ── nắm ba điểm sau là đủ.

  • Máy khách Windows đã hỗ trợ. Windows 11 lấy Windows Hello làm authenticator, hỗ trợ tạo, dùng, quản lý passkey (Cài đặt > Tài khoản > Passkeys); có TPM thì khóa riêng được bảo vệ phần cứng.10 WebAuthn qua trình duyệt (Edge/Chrome) trên Windows 10 cũng chạy.
  • Môi trường Entra ID thì bật “passkey = phương thức xác thực FIDO2”. Microsoft Entra ID hỗ trợ security key và passkey trong ứng dụng Microsoft Authenticator (gắn thiết bị); đòi “MFA kháng phishing” bằng cường độ xác thực của truy cập có điều kiện thì giới hạn truy cập tài nguyên đích vào passkey, v.v.9 Chuyển từ thế giới NTLM và chính sách hạn mật khẩu không một bước xong, nên song song kiểm kê nền xác thực đã xử trong bài NTLM và Kerberos, trước hết bắt buộc MFA kháng phishing từ tài khoản quản trị viên là lối quen.
  • Ứng dụng web nội bộ cũng cùng lợi ích. Tuy nhiên HTTPS là tiền đề. WebAuthn API chỉ chạy trong secure context, nên ứng dụng intranet cũng (trừ localhost lúc phát triển) cần HTTPS hóa và chỉnh tên domain nội bộ dùng được làm RP ID trước. Xong thì RP ID cũng chạy với domain nội bộ. Nghĩa là từ bỏ giấy dán mật khẩu, nội bộ ra hiệu quả sớm hơn dịch vụ ra ngoài cũng không lạ.

8. Tóm tắt

  • Điểm yếu mật khẩu không phải độ mạnh, mà cấu trúc “chia sẻ bí mật rồi gửi mỗi lần xác thực”. Bí mật tồn tại ở người dùng, ô nhập, đường truyền, máy chủ nên nhiều mục tiêu tấn công. Thêm mã một lần, phishing kiểu AiTM vẫn chuyển tiếp rồi thắng.
  • Passkey là cặp khóa mật mã khóa công khai theo từng site; máy chủ chỉ nhận khóa công khai lộ cũng không lợi dụng được, lúc đăng nhập chỉ gửi chữ ký trên challenge dùng một lần. Máy chủ không có bí mật, đường truyền cũng không chảy bí mật.
  • Chữ ký nung origin và RP ID trình duyệt đã xác nhận, nên trên site giả passkey của thật không hiện ứng viên, chuyển tiếp cũng rớt lúc xác minh. Người dùng không cần nhận ra site giả chính là bản chất “kháng phishing”; căn cứ phòng thủ đã chuyển từ sự chú ý của con người sang cấu trúc giao thức.
  • Passkey đồng bộ đồng bộ bằng mã hóa đầu cuối, mạnh trước đổi máy, mất máy. Đổi lại chỗ phải giữ gom vào tài khoản đám mây, nên phòng thủ chính Apple ID/tài khoản Google là tiền đề. Doanh nghiệp còn chọn kiểu gắn thiết bị (security key, passkey Authenticator của Entra ID).
  • Passkey không xóa tấn công mà đẩy sang chỗ yếu. Mật khẩu song song, luồng khôi phục tài khoản, đánh cắp phiên còn là mặt tấn công; lõi đưa vào nằm ở thu hẹp có kế hoạch các phương tiện dự phòng và tăng cường luồng khôi phục.
  • Triển khai là hai hàm create / get của WebAuthn API + xác minh máy chủ. Đừng tự viết xác minh, giao thư viện có thành tích, dồn sức vào quản lý challenge, UI nhiều passkey, thiết kế khôi phục.

Bài viết liên quan

Lĩnh vực tư vấn liên quan

KomuraSoft LLC nhận hỗ trợ triển khai WebAuthn đăng nhập passkey cho hệ thống web nội bộ, thiết kế triển khai MFA kháng phishing trên môi trường Entra ID, và Custom Software Development gồm gắn xác thực vào ứng dụng nghiệp vụ Windows như WinForms/WPF.

  1. FIDO Alliance, PasskeysHow FIDO Works. Về passkey là thông tin xác thực FIDO thay mật khẩu; thông tin sinh trắc không gửi từ thiết bị, chỉ dùng đối chiếu cục bộ; tháng 5 năm 2022 Apple, Google, Microsoft cùng tuyên bố mở rộng hỗ trợ không mật khẩu dựa chuẩn FIDO; dùng xuyên thiết bị (cross-device) dùng cách lai QR và xác nhận gần bằng Bluetooth.  2 3 4 5

  2. W3C, Web Authentication: An API for accessing Public Key Credentials Level 2 (khuyến nghị W3C). Về WebAuthn là API tạo và dùng thông tin xác thực dựa mật mã khóa công khai; khóa riêng của thông tin xác thực giữ trong authenticator, phía máy chủ (Relying Party) chỉ đăng ký khóa công khai và credential ID; xác thực diễn ra bằng chữ ký (assertion) trên challenge máy chủ gửi; về mục tiêu thiết kế phạm vi và bảo vệ thông tin xác thực. Cùng lúc bài viết cũng tham chiếu API chỉ công khai trong secure context; RP ID bỏ thì thành domain hiệu lực của origin gọi; user handle (user.id) là giá trị mờ tối đa 64 byte, không nên chứa thông tin nhận diện cá nhân như tên người dùng hay địa chỉ email (§14.6.1 User Handle Contents).  2 3 4 5

  3. W3C, Web Authentication Level 2 — §5.1.3 Create / RP ID validation, §13.4.9 Regarding phishing. Về thông tin xác thực khóa công khai được scope theo RP ID (định danh Relying Party = domain); trình duyệt (client) xác minh tương ứng giữa domain đăng ký được của origin gọi và RP ID, không tương ứng thì từ chối tạo/dùng thông tin xác thực; nhờ đó origin giả không truy cập được thông tin xác thực của site khác, WebAuthn có kháng phishing kể cả kiểu trung gian.  2 3

  4. CISA, Implementing Phishing-Resistant MFA (tờ thông tin tháng 10 năm 2022). Về MFA dùng SMS, thoại, thông báo đẩy, OTP yếu trước phishing, tấn công AiTM (chuyển tiếp), tấn công mệt MFA; cách kháng phishing nêu FIDO/WebAuthn và xác thực dựa PKI (thẻ thông minh, v.v.), FIDO/WebAuthn được đặt gold standard; tổ chức nên chuyển tài khoản rủi ro cao sang MFA kháng phishing trước.  2

  5. W3C, Web Authentication Level 2 — §7.2 Verifying an Authentication Assertion. Về quy trình xác minh phía máy chủ quy định kiểm type, challenge (khớp cái mình phát), origin của clientDataJSON; xác minh rpIdHash trong authenticatorData khớp hash SHA-256 của RP ID kỳ vọng; xác nhận cờ User Present / User Verified; xác minh chữ ký bằng khóa công khai đã lưu.  2 3

  6. NIST, Incorporating Syncable Authenticators Into NIST SP 800-63B (phụ lục tháng 4 năm 2024, gộp vào SP 800-63B bản 4). Về authenticator đồng bộ được (passkey đồng bộ) khi khóa riêng được lưu và nhân bản trên vải đồng bộ thỏa yêu cầu thì có thể đạt AAL2; authenticator mật mã AAL3 đòi môi trường bảo vệ/cô lập bằng phần cứng nên authenticator đồng bộ xuất được khóa riêng thì không dùng cho AAL3; cách xác minh origin như WebAuthn được sắp xếp là có kháng mạo danh bên xác minh (kháng phishing). PDF gốc là NIST SP 800-63B Supplement 1 2 3 4

  7. Hỗ trợ Apple, Về bảo mật của passkey. Về passkey đồng bộ qua iCloud Keychain; iCloud Keychain mã hóa đầu cuối, Apple cũng không đọc được; đồng bộ được bảo vệ bằng khóa trên thiết bị người dùng, có khôi phục qua escrow giới hạn tốc độ. 

  8. Google, Bảo mật passkey trong Google Password Manager. Về khóa riêng của passkey được mã hóa trên thiết bị rồi mới đồng bộ; mã hóa đầu cuối khiến chính Google cũng không truy cập nội dung khóa riêng; khôi phục đòi bảo vệ dựa khóa màn hình thiết bị, v.v. 

  9. Microsoft Learn, Bật xác thực FIDO2 (passkey) trên Microsoft Entra ID. Về Entra ID hỗ trợ xác thực không mật khẩu kháng phishing bằng FIDO2 security key và passkey Microsoft Authenticator (gắn thiết bị); bật bằng chính sách phương thức xác thực và đòi bằng cường độ xác thực của truy cập có điều kiện (MFA kháng phishing).  2

  10. Microsoft Learn, Hỗ trợ passkey trên Windows. Về Windows 11 hỗ trợ tạo và dùng passkey qua Windows Hello; passkey đã lưu quản từ Cài đặt > Tài khoản > Passkeys; thông tin xác thực Windows Hello được bảo vệ phần cứng khi có TPM; passkey trên thiết bị di động dùng được qua QR. 

Các bài viết gần đây có cùng thẻ để tìm hiểu sâu hơn những chủ đề lân cận.

Các trang này đặt chủ đề trong bối cảnh rộng hơn của dịch vụ và quyết định.

Câu hỏi thường gặp

Các câu hỏi thường gặp khi tư vấn về chủ đề của bài viết.

Khác biệt gốc giữa passkey và mật khẩu là gì?
Mật khẩu là cơ chế "người dùng và máy chủ chia sẻ cùng một bí mật, mỗi lần đăng nhập lại gửi bí mật đó". Bí mật tồn tại khắp nơi ── trong đầu người dùng, ô nhập, đường truyền, cơ sở dữ liệu máy chủ ── nên tất cả đều thành mục tiêu tấn công. Passkey dùng cặp khóa mật mã khóa công khai; khóa riêng không bao giờ gửi lên máy chủ. Kiểu gắn thiết bị thì khóa riêng không rời authenticator; kiểu đồng bộ cũng chỉ ra ngoài dưới dạng mã hóa đầu cuối. Máy chủ chỉ lưu khóa công khai, thông tin "lộ cũng không lợi dụng được", và lúc đăng nhập chỉ gửi chữ ký trên challenge dùng một lần. Tức bí mật dùng chung vốn là điểm yếu của mật khẩu đơn giản không tồn tại. Thêm nữa cặp khóa được tạo riêng từng site nên khái niệm dùng lại cũng không thành.
Thông tin sinh trắc (vân tay, khuôn mặt) có gửi lên máy chủ không?
Không gửi. Dữ liệu vân tay hay khuôn mặt chỉ dùng để đối chiếu cục bộ trong thiết bị, để mở cửa két chứa khóa riêng; theo thiết kế FIDO, thông tin sinh trắc không được gửi ra ngoài thiết bị. Máy chủ chỉ nhận chữ ký có cờ "đã xác minh người dùng" (user verification); không có vân tay, cũng không có vector đặc trưng sinh trắc. Chỗ không dùng được sinh trắc thì thay bằng PIN; PIN này cũng giống PIN Windows Hello, chỉ đối chiếu cục bộ trên thiết bị, điểm khác quyết định với mật khẩu là không đi trên mạng.
Vì sao passkey kháng phishing?
Vì về cơ chế, người dùng vốn không cần nhận ra site giả. Passkey được tạo gắn với domain của site (RP ID), và trình duyệt chỉ đưa ra ứng viên passkey khớp domain đang hiển thị. Dù vào domain giả trông y hệt thật, passkey của site thật không hiện trong lựa chọn, nên người dùng không thể bị lừa dùng. Thêm nữa chữ ký nung origin mà trình duyệt đã xác nhận và hash của RP ID, nên dù chữ ký bị chuyển tiếp, phía máy chủ thật vẫn từ chối lúc xác minh. Tai nạn "nhập thông tin xác thực thật vào site giả" vốn hành hạ mật khẩu và mã SMS, về cấu trúc không làm được ── đó là khác biệt gốc với biện pháp dựa vào huấn luyện và cảnh giác.
Mất điện thoại thì không vào được tài khoản?
Passkey kiểu đồng bộ (lưu trong iCloud Keychain hay Google Password Manager) thì khôi phục được sang thiết bị mới đã đăng nhập cùng Apple ID/tài khoản Google. Tuy nhiên khôi phục kho mã hóa đầu cuối không chỉ cần mật khẩu tài khoản mà còn xác minh danh tính thêm, như nhập khóa màn hình (passcode) của máy cũ, nên mất luôn các phương tiện khôi phục đó thì có thể không khôi phục được. Thế đứng không gửi hết vào một chiếc điện thoại là quan trọng. Kiểu gắn thiết bị (security key, Windows Hello, v.v.) chung số phận với máy, nên tài khoản quan trọng hãy đăng ký nhiều passkey. Nhiều dịch vụ cho đăng ký nhiều passkey trên một tài khoản. Vô hiệu hóa khi mất khác nhau theo loại. Kiểu đồng bộ thì bản sao trên mọi thiết bị là cùng một thông tin xác thực, nên trước hết phía tài khoản nền tảng hãy xóa thiết bị đã mất hoặc remote wipe để bản trên máy đó không dùng được (xóa passkey đó trong cài đặt tài khoản phía dịch vụ thì bản sao mọi thiết bị bị vô hiệu một lượt). Kiểu gắn thiết bị thì xóa passkey của authenticator đó phía dịch vụ là vô hiệu hóa đúng khóa đã mất. Dùng trong tổ chức thì thiết kế bộ "dự phòng để người dùng tự phục hồi" và "quy trình quản trị viên thu hồi khi mất".
Passkey cũng có điểm yếu?
Có. Nói chính xác hơn là chỗ yếu dịch đi. Bản thân xác thực được mật mã khóa công khai làm cứng, nên kẻ tấn công nhắm phần xung quanh yếu hơn. Cụ thể: nếu phương tiện cũ như mật khẩu hay SMS vẫn tồn tại song song thì đó còn là mắt xích yếu nhất; thủ đoạn lợi dụng luồng khôi phục tài khoản để đăng ký passkey của chính kẻ tấn công; kiểu đồng bộ thì chiếm tài khoản đám mây thành điểm lỗi đơn mới. Tấn công đánh cắp cookie phiên sau đăng nhập passkey cũng không chặn được, nên mối đe dọa không liên quan không biến mất. Khi đưa vào, không chỉ "thêm passkey" mà còn phải thiết kế tăng cường luồng khôi phục và thu hẹp có kế hoạch các phương tiện dự phòng.

Hồ sơ tác giả

Trang giới thiệu tác giả bài viết.

Go Komura

Đại diện của KomuraSoft LLC

Chuyên về phát triển phần mềm Windows, tư vấn kỹ thuật và điều tra lỗi, đặc biệt trong các dự án có hệ thống hiện hữu và lỗi khó tái hiện.

Liên kết công khai

Quay lại blog