Vì sao mã TOTP thất bại khi đồng hồ thiết bị lệch
Mã là một hàm băm của bí mật và bước thời gian hiện tại. Hãy so sánh độ lệch ở hai đầu, rồi chỉnh đồng hồ thay vì mở rộng cửa sổ.
Mã dùng một lần có thể hoàn toàn đúng trên điện thoại của bạn và vẫn bị máy chủ từ chối trong cùng giây đó. Hai bên tính cùng một hàm từ một bí mật chia sẻ và bước thời gian hiện tại, nên bất đồng về thời gian tạo ra bất đồng về mã. Điều đó khiến việc đồng hồ lệch là một lỗi liên quan đến bảo mật chứ không chỉ là điều khó chịu.
Ở đây có hai đồng hồ quan trọng, và chỉnh cái nhìn thấy được là phần mọi người làm trước. Cái thường cần chú ý là cái kia.
Mã là một hàm của thời gian, không phải mật khẩu
TOTP lấy bí mật chia sẻ và một bộ đếm dẫn xuất từ thời gian hiện tại, cho cả hai đi qua một hàm băm có khóa và cắt kết quả thành một chuỗi thập phân ngắn, như quy định trong RFC 6238. Bộ đếm tiến lên ở mỗi bước thời gian, thường là ba mươi giây, nên cùng một bí mật tạo ra giá trị mới khi bước thay đổi. Bên xác minh tính lại giá trị mong đợi cho bước hiện tại và so sánh, việc này đòi hỏi cùng bí mật và cùng quan niệm về hiện tại. Mật khẩu vẫn dùng lại được cho đến khi bị đổi, trong khi giá trị này hết hạn ở một ranh giới mà máy khách không thấy.
Đó là lý do một mã hoạt động còn mã tiếp theo thất bại vài khoảnh khắc sau. Điều này cũng giải thích vì sao sao chép mã từ tin nhắn trò chuyện lại là thói quen thiếu tin cậy đến vậy.
Hai đồng hồ phải khớp nhau, không phải một
Dữ liệu đăng ký là thứ chia sẻ đầu tiên, và thời gian là thứ thứ hai. Nếu bí mật đúng trong khi đồng hồ lệch nhiều hơn cửa sổ cho phép, mọi giá trị được tạo ra đều rơi vào bước sai và bị từ chối. Nếu đồng hồ khớp nhau trong khi bí mật sai, mọi giá trị cũng bị từ chối, và cả hai thất bại trông giống hệt nhau từ màn hình đăng nhập. Tách chúng ra nghĩa là kiểm tra mục tài khoản và thời gian một cách độc lập, theo đúng thứ tự đó.
Đồng hồ của bên xác minh cũng đáng được soi xét như đồng hồ của thiết bị. Một máy chủ có nguồn thời gian hỏng sẽ từ chối mã đúng của mọi người dùng cùng lúc, và các báo cáo sẽ mô tả một sự cố đột ngột chứ không phải độ lệch. Nên nhận ra kiểu mẫu này, vì cách sửa nằm ở máy chủ chứ không phải ở một trăm chiếc điện thoại.
Mở rộng cửa sổ tốn gì
Các bản triển khai có thể chấp nhận mã từ bước liền kề để hấp thụ khác biệt nhỏ, và sự dễ dãi đó là quyết định thiết kế chứ không phải điều chỉnh miễn phí. Mỗi bước thêm vào nhân số giá trị hợp lệ tại bất kỳ thời điểm nào, đúng là điều kẻ tấn công đoán mã ưa thích. Quy tắc chống lặp lại cũng quan trọng vì lý do tương tự, vì một mã được chấp nhận hai lần là mã đã rò rỉ một cách hữu ích. Một quản trị viên mở rộng cửa sổ để dập tắt phàn nàn đang đổi một thuộc tính thật lấy một cải thiện bề ngoài.
Chỉnh đồng hồ là sửa chữa, còn mở rộng cửa sổ là thuốc an thần. Cách đầu loại bỏ nguyên nhân, cách sau che giấu nó.
Kiểm tra cả hai đồng hồ trước khi thử lại
Đọc giờ trên thiết bị và trên máy chủ, rồi so sánh độ lệch thay vì giờ địa phương hiển thị. Các lệnh dưới đây cho thấy trạng thái đồng bộ và thời điểm UTC thô trên một máy chủ Linux. Hãy chạy chúng ở cả hai đầu trước khi thay đổi bất kỳ cài đặt xác thực nào.
timedatectl
date -u +'%Y-%m-%dT%H:%M:%SZ'
chronyc tracking
timedatectl timesync-status
Độ lệch đo bằng giây là vô hại, độ lệch đo bằng phút giải thích một lần từ chối, và một hệ thống không báo cáo nguồn đồng bộ nào là ứng viên cho cả hai. Hãy so sánh trực tiếp hai dấu thời gian UTC, vì giờ địa phương bao gồm một múi giờ mà thuật toán không bao giờ thấy. Nếu độ lệch nhỏ mà mã vẫn thất bại, hãy ngừng chỉnh đồng hồ và thay vào đó kiểm tra mục đăng ký. Những lần thử lặp lại vào một tài khoản bị khóa khiến lỗi ban đầu khó quan sát hơn.
Ghi lại thời điểm từ chối, độ lệch và nội dung lỗi, và để bí mật chia sẻ ra ngoài đó. Bộ phận hỗ trợ có thể làm việc với ba mục đầu và không bao giờ nên thấy mục thứ tư.