password.es đã sai ở đâu, và giờ thì không nữa

Đăng ngày bởi David Carrero

Blog này có mười hai bài giải thích mọi thứ nên làm thế nào: rằng độ dài quan trọng hơn ký tự đặc biệt, rằng trình quản lý không phải sự tiện lợi mà là cách duy nhất giữ được quy tắc, rằng một tỷ lệ phần trăm chẳng nói lên điều gì.

Viết ra thì dễ. Khó chịu là khi nhìn chính trang của mình bằng đúng thước đo ấy. Chúng tôi đã nhìn, và có ba thứ sai. Chúng nằm nguyên ở đây, kèm những con số đã tố cáo chúng, vì một trang về bảo mật chỉ công bố cái đúng của mình thì đáng giá kém hẳn.

Trình kiểm tra bị đơ trong khi bạn gõ

Trình kiểm tra phân tích mật khẩu của bạn bằng zxcvbn, một thư viện tìm mẫu thay vì đếm chữ hoa. Nó chạy rất tốt và có cái giá: nó chạy nguyên khối, trên đúng luồng đang vẽ trang. Trong lúc nó chạy, trình duyệt không làm được gì khác.

Cái giá ấy tăng nhanh theo độ dài. Đo bằng đúng gói mà trang phục vụ, với những mật khẩu người ta thật sự gõ — từ ngữ, năm sinh, @ thay cho a:

độ dài một lần chạy
16 ký tự 45 ms
20 ký tự 121 ms
32 ký tự 273 ms
64 ký tự 843 ms
128 ký tự 3.621 ms

Đến đây vẫn bình thường. Vấn đề là chúng tôi chạy nó bao nhiêu lần.

Ô nhập có gắn hai bộ lắng nghe khác nhau, inputkeyup. Một phím thường kích hoạt cả hai. Thế nên mỗi chữ bạn gõ, toàn bộ phân tích chạy hai lần: 90 ms với mật khẩu 16 ký tự, nửa giây với 32 ký tự.

Và chẳng có gì hãm nó lại: không hẹn giờ, không giới hạn độ dài, không luồng riêng. Từ khoảng hai mươi ký tự trở đi, trình duyệt phân tích lâu hơn thời gian bạn bấm phím kế tiếp. Các lần gõ chất đống trong một hàng đợi không bao giờ vơi, và trang ngừng phản hồi trong khi bạn gõ. Dán một mật khẩu dài làm nó đơ vài giây.

Cách sửa là hai thay đổi nhỏ. Chúng tôi gỡ bộ lắng nghe keyup, vì input đã bao gồm gõ, dán, xóa và tự động điền của trình quản lý: một nửa công việc biến mất mà không đổi bất cứ thứ gì bạn thấy. Và thêm 150 mili giây chờ: trong lúc bạn gõ thì không phân tích gì, và phân tích ngay khi bạn dừng. Không ai gõ chậm đến mức nhận ra.

Kết quả giống hệt. Barcelona1992$ vẫn nói đúng những điều cũ: rằng «barcelona» có trong từ điển, rằng 1992 trông như một năm, và rằng nó đổ trong chưa tới một giây.

Mô tả bị cắt giữa câu ở mười lăm ngôn ngữ

Chuyện này ngớ ngẩn hơn và ngượng hơn.

Câu xuất hiện dưới tiêu đề trên công cụ tìm kiếm — meta description — bị cắt cụt ở mười lăm trong mười tám ngôn ngữ của trình kiểm tra. Chỉ tiếng Tây Ban Nha, tiếng Hàn và tiếng Nhật thoát. Ai đó có lúc đã cắt bớt theo độ dài, cắt giữa từ, và sau đó không ai nhìn lại.

Ở ba ngôn ngữ, nhát cắt rơi đúng giữa một ký tự đặc biệt, nên thứ chúng tôi đăng lên Google là thế này:

ngôn ngữ thứ chúng tôi phục vụ đáng lẽ phải là
Bồ Đào Nha …datas e padr&o padrões
Thổ Nhĩ Kỳ …arıyor ve ger&cced gerçekten
Việt …chúng tôi tra mật kh&# mật khẩu

Điều đáng chú ý là nó nằm ở đâu: trên trang chạy tốt nhất của cả website. Trình kiểm tra chuyển đổi tốt hơn hẳn trình tạo, và làm điều đó với một mô tả hỏng. Cả mười lăm đã được hoàn chỉnh.

Nhân tiện, ở tiếng Hàn, tiếng Nhật và tiếng Việt, thương hiệu đã chuyển từ đầu xuống cuối tiêu đề. Trên kết quả tìm kiếm tên miền vốn đã hiện riêng, nên mở đầu bằng «password.es ·» chỉ phí đúng chỗ đắt giá nhất.

Một thiên lệch một phần trăm triệu

Trình tạo chọn từng ký tự bằng crypto.getRandomValues(), nguồn ngẫu nhiên tử tế của trình duyệt. Nhưng để biến con số khổng lồ đó thành «một vị trí trong bảng chữ cái», chúng tôi dùng phép chia lấy dư, và ở đó có một cái bẫy kinh điển: 2³² không phải bội của 83, nên những vị trí đầu bảng chữ cái ra hơi thường xuyên hơn những vị trí cuối.

Hơi là bao nhiêu: với bảng chữ cái tới 89 ký tự, cỡ một phần trăm triệu. Nó không đổi gì cả. Nó không làm mật khẩu của bạn yếu đi một cách đo đếm được, còn xa mới tới.

Chúng tôi vẫn sửa, và nó gọn trong ba dòng: bỏ 45 giá trị dư trong 4.294.967.296 giá trị khả dĩ rồi bốc lại. Ở một trang về mật khẩu, «không đáng kể» không phải lý do tốt để giữ lại một thiên lệch khi gỡ nó rẻ đến thế.

Thứ còn thiếu: để trình duyệt thi hành lời hứa

Chúng tôi có hẳn một bài giải thích rằng mật khẩu của bạn không rời khỏi đây. Điều đó là thật, và dù vậy nó chỉ là một câu của chúng tôi: về mặt kỹ thuật chẳng có gì ngăn một đoạn mã bị chèn làm chuyện khác.

Giờ mỗi trang đều mang một chính sách bảo mật nội dung. Hai phần quan trọng:

  • Không đoạn mã nào chạy nếu nó không có trong trang lúc dựng. Mỗi đoạn mã hợp lệ được ký bằng dấu vân tay của nó; đoạn bị chèn không khớp và trình duyệt từ chối chạy.
  • connect-src 'none'. Trang không thực hiện một yêu cầu mạng nào từ JavaScript, và giờ chính trình duyệt áp đặt điều đó. Nếu một ngày có thứ gì định gửi những gì bạn gõ đi đâu đó, nó sẽ không ra được.

Lời hứa thôi làm một tuyên bố và trở thành một quy tắc.

Những gì vẫn còn sai

Cập nhật ngày 31 tháng 8. Cả ba điều trong phần này đã được sửa ngay trong ngày bài viết lên trang: mười lăm ngôn ngữ giờ mô tả đúng động cơ thật, hai thang đo đã thành một, và phần hỏi đáp của trình kiểm tra giải thích chuyện ký tự đặc biệt. Chúng vẫn được giữ lại, vì bản ghi những gì từng sai đáng giá hơn tấm ảnh một trang web hoàn hảo.

Đây là chỗ bài viết này xứng đáng có mặt.

Mười lăm ngôn ngữ vẫn mô tả trình kiểm tra như động cơ cũ. Văn bản của những trang đó nói rằng nó tái tạo logic kinh điển của PasswordMeter. Không còn nữa: động cơ ấy bị thay vì nó gọi Matkhau1! là rất mạnh và đánh trượt một cụm năm từ, tức là ngược hẳn điều cần nói. Tiếng Tây Ban Nha, tiếng Hàn và tiếng Nhật đã cập nhật; mười lăm ngôn ngữ còn lại thì chưa.

Có hai thang đo khác nhau trong cùng một nhà. Trang chủ quyết định mật khẩu mạnh hay không theo số bit; trình kiểm tra quyết định theo thời gian cần để phá. Hai tiêu chí khác nhau, và chẳng chỗ nào chúng tôi báo cho bạn.

Trình tạo và trình kiểm tra không đếm cùng một bộ ký tự đặc biệt: một bên dùng 27, bên kia giả định 33. Chênh lệch nhỏ, nhưng có thật.

Không cái nào trong ba cái là nghiêm trọng. Cả ba là nợ, và chúng thà được viết ra ở đây còn hơn chờ người khác tìm thấy.

Nhật ký thay đổi của phiên bản này

Vì kho mã không công khai, nhật ký thay đổi nằm nguyên ở đây. Phiên bản 0.2.0, ngày 31 tháng 8 năm 2026:

Thêm. Chính sách bảo mật nội dung cho từng trang, kèm dấu vân tay của mỗi đoạn mã. Bài viết về nơi lưu mật khẩu đã lưu của bạn, trong cả mười tám ngôn ngữ. Một hàng đợi biên tập quyết định viết gì, và ra lệnh không đăng gì khi nó cạn.

Sửa. Mô tả của trình kiểm tra, bị cắt giữa câu ở mười lăm ngôn ngữ, ba trong số đó có một ký tự bị xẻ đôi. Việc tab đơ khi gõ. Thiên lệch khi bốc ngẫu nhiên. Và tấm ảnh còn thiếu ở bài trước.

Đổi. Tiêu đề trình kiểm tra ở tiếng Hàn, tiếng Nhật và tiếng Việt. Việc triển khai, giờ được kích hoạt khi trang đã dựng xong tồn tại chứ không phải một phút trước đó. Và các bản dịch tiếng Việt, Hindi và Ả Rập, thôi chặn một lần xuất bản dù vẫn là những bản yếu nhất.


Các con số trong bài này là đo được, không phải ước lượng: thời gian zxcvbn với đúng gói mà trang phục vụ và những mật khẩu có từ ngữ cùng phép thay thế; thiên lệch khi bốc, tính trên 4.294.967.296 giá trị của một số nguyên 32 bit. Động cơ của trình kiểm tra là zxcvbn, mã nguồn mở.

Ảnh của Ernandes Alves · Pexels

← Quay lại blog