Bạn mở ứng dụng VPN, gõ mật khẩu, và sáu chữ số từ ứng dụng xác thực trả về là không hợp lệ — hai lần, rồi lần thứ ba. Không có gì thay đổi trên tài khoản từ hôm qua, nên phản xạ đầu tiên là xóa mục trong ứng dụng xác thực và quét lại — thường đó là cách sửa sai. Mã dùng một lần không phải mật khẩu thứ hai: cổng phải yêu cầu nó ở một bước cụ thể, từ một mục đã đăng ký cụ thể, trong một khung thời gian cụ thể, và phần lớn các lần từ chối xảy ra trước khi các chữ số được so sánh. Hãy xác định bạn đang ở bước nào trước khi chạm vào phần đăng ký.

Thứ tự lời nhắc cho biết bạn đang ở luồng nào

Ba dạng bao phủ gần như mọi lần đăng nhập VPN có mã. Ở dạng hai bước, ứng dụng gửi mật khẩu, máy chủ phát ra thử thách, và ứng dụng hỏi lại. Ở dạng kết hợp, cổng muốn mật khẩu và mã trong một lần gửi — đôi khi nối liền, đôi khi sau một dấu phân cách mà chỉ nhà vận hành ghi lại. Ở dạng trình duyệt, ứng dụng không có trường nào cả: mã được nhập vào một trang web, hoặc một phê duyệt đẩy thay thế nó, và ứng dụng máy tính chờ kết quả.

Sai dạng trông giống mã tồi. Dán một mã mới vào trường chỉ dành cho mật khẩu, và máy chủ sẽ đọc nó như một phần của mật khẩu. Ở phía ứng dụng, OpenVPN 2.4 và mới hơn làm cho sự khác biệt trở nên rõ ràng: máy chủ trả lời bằng AUTH_FAILED,CRV1: mong đợi một phản hồi thử thách, nên hồ sơ cần static-challenge hoặc tệp mật khẩu ở dạng SCRV1:. Một hồ sơ cũ chỉ mang auth-user-pass sẽ xác thực mật khẩu rồi dừng lại, điều này trong nhật ký trông như lỗi OTP dù không có mã nào được gửi.

WireGuard đáng được nêu là ngoại lệ: nó xác thực các cặp khóa chứ không phải con người, nên không có trường cho mã. Nếu một nhà cung cấp quảng cáo loại này, thì có thứ gì đó ngoài đường hầm đang chấp nhận nó.

Máy chủ làm gì với sáu chữ số

Mã dựa trên thời gian tuân theo RFC 6238, bao bọc cấu trúc dựa trên bộ đếm cũ hơn từ RFC 4226: một HMAC trên một nhân tố di chuyển, bị cắt còn sáu chữ số theo mặc định. Với TOTP, nhân tố di chuyển là thời gian Unix hiện tại chia cho một bước, 30 giây trừ khi nhà vận hành đã đổi. Trình xác minh không bao giờ so sánh các chữ số của bạn với một giá trị đã lưu; nó tính lại mã mong đợi từ hạt giống chia sẻ và thường chấp nhận cả các bước lân cận, nên một vòng đi về chậm không làm hỏng việc đăng nhập.

Hai hệ quả thường bị bỏ qua. Múi giờ của điện thoại không liên quan, vì hạt giống không bao giờ nhìn thấy đồng hồ địa phương — chỉ độ lệch so với UTC thật mới quan trọng, và một thiết bị chạy nhanh hai phút sẽ thất bại ở mọi mã trong khi vẫn hiển thị đếm ngược sạch sẽ. Và mã là dùng một lần theo thiết kế: trình xác minh ghi nhớ giá trị bộ đếm cuối cùng mà nó chấp nhận cho hạt giống đó, nên chính những chữ số đó gửi lại sẽ bị từ chối ngay cả trong cùng khung. Một ứng dụng thử lại sau khi hết thời gian có thể đốt luôn mã vừa gửi.

Các mã thông báo dựa trên bộ đếm dịch bộ đếm mỗi lần nhấn, nên chúng lệch đồng bộ sau khi mã được tạo nhưng chưa bao giờ gửi; cách sửa thông thường là một khung đồng bộ lại chấp nhận vài giá trị phía trước. Nếu nhà vận hành đăng ký HOTP còn ứng dụng của bạn hiển thị TOTP, mọi giá trị đều sai theo cách trông như vấn đề đồng hồ. URI cấp phát phía sau mã QR nêu loại, số chữ số, chu kỳ và hàm băm.

Những thất bại trông như mã sai

Mục đã đăng ký là thủ phạm phổ biến nhất. Ứng dụng xác thực gắn nhãn các mục theo nhà phát hành và tài khoản, nên ai có hai danh tính trên cùng một VPN có thể có hai mục mà nhãn khác nhau đúng một ký tự. Mã chỉ có giá trị cho hạt giống đã tạo ra nó và không gì khác. Hãy so nhãn trên điện thoại với tên người dùng mà máy chủ ghi lại, không so với điều bạn nhớ là mình đã gõ.

Thứ hai là một bộ tham số không khớp. Một hạt giống đăng ký với tám chữ số, chu kỳ 60 giây hoặc SHA-256 tạo ra những mã mà trình xác minh mong đợi sáu chữ số, 30 giây và SHA-1 sẽ từ chối, và ở phía ứng dụng điều đó không thể phân biệt với mã sai. Nó xuất hiện sau các lần di chuyển khi mục được thêm lại từ ảnh chụp mã QR, hoặc khi bản ghi mã thông báo được dựng lại bằng giá trị mặc định.

Thứ ba không phải về mã. Cổng thường trả về một lỗi xác thực chung cho mật khẩu sai, mã hết hạn và tài khoản bị vô hiệu hóa, cố ý, để không ai có thể dò xem nhân tố nào đã thất bại. Hãy đọc nhật ký của cổng hoặc RADIUS thay vì biểu ngữ của ứng dụng: một thử thách chưa bao giờ phát ra, một lần từ chối truy cập không có thuộc tính OTP và một lần từ chối theo chính sách trông giống nhau trên màn hình và dẫn đến các bước tiếp theo khác nhau.

Một trình tự ngắn giúp thu hẹp

Bắt đầu bằng kiểm tra rẻ nhất và dừng ở bước đầu tiên không đứng vững.

  1. Chờ một mã mới, gửi nó một lần, và ghi lại xem thử thách xuất hiện trước hay sau khi mật khẩu được chấp nhận.
  2. Khớp nhãn trong ứng dụng xác thực với tên người dùng mà máy chủ lưu.
  3. Xác nhận rằng hồ sơ có thể trả lời một thử thách, như trong trường hợp CRV1 ở trên.
  4. So đồng hồ của thiết bị với một nguồn thời gian đã biết; độ lệch hơn vài chục giây tự nó phá hỏng TOTP.
  5. Hỏi nhà vận hành xem mã thông báo là TOTP hay HOTP, và những chữ số, chu kỳ, hàm băm nào đã được đăng ký.

Hai quy tắc ngăn điều này làm mọi thứ tệ hơn. Đừng thử lại nhiều lần: nhiều cổng đếm số lần thất bại theo tài khoản và hoặc khóa tài khoản hoặc bắt đầu trì hoãn phản hồi, nên một đợt dồn dập biến một lỗi cấu hình nhỏ thành một phiếu hỗ trợ. Và đừng đăng ký lại mã thông báo để chẩn đoán, vì điều đó làm hạt giống cũ mất hiệu lực; nếu lỗi thật là một thử thách mà ứng dụng chưa bao giờ gửi, giờ bạn có hai thay đổi để giải thích thay vì một.

Giữ hạt giống và mã khôi phục ngoài vòng lặp

Sáu chữ số và bí mật đằng sau chúng không thể hoán đổi cho nhau. Một mã QR cấp phát hoặc hạt giống Base32 tạo ra mọi mã tương lai của tài khoản, nên nó thuộc cùng loại với mật khẩu: không trong ảnh chụp màn hình, không trong bình luận phiếu, không trong trò chuyện với người đã liên hệ bạn trước. Mã khôi phục là cơ chế riêng — dùng một lần, thường bỏ qua hoàn toàn lời nhắc mã, và tiêu một cái để thử tài khoản sẽ xóa mất đường dự phòng mà bạn có thể cần sau này.

Mã cũng không làm cho trang đăng nhập đáng tin: một lời nhắc OTP trên miền trông giống thật sẽ thu một mã hợp lệ và phát lại nó trong khung, còn chứng chỉ vẫn là thứ cho bạn biết mình đang gõ ở đâu.

Nếu trình tự dừng ở một hồ sơ không thể trả lời thử thách, hãy sửa hồ sơ và kiểm tra lại bằng một mã mới. Nếu nó dừng ở tham số đăng ký không khớp, hãy nhờ nhà vận hành đọc bản ghi mã thông báo trước khi ai đó quét bất cứ thứ gì. Nếu nó dừng ở tình trạng khóa, hãy chờ cho qua thay vì đổi ứng dụng — trạng thái tài khoản là rào cản, không phải ứng dụng.

Bài viết liên quan