Khi một trang web bảo rằng mật khẩu của bạn phải mất ba triệu năm mới bẻ được, nó đang bỏ đi phần quan trọng nhất của câu. Câu hỏi đúng không phải là mất bao lâu. Là mất bao lâu để chống lại cái gì.
Và câu trả lời cho chống lại cái gì thì không do bạn quyết. Nó được quyết bởi một lập trình viên của cái cửa hàng nơi bạn mua một đôi giày năm 2019, vào lúc anh ta chọn cách cất mật khẩu của bạn trong cơ sở dữ liệu. Bạn gõ đúng một chuỗi hai mươi ký tự y hệt nhau ở cả hai nơi. Chỗ này nó trụ được hàng thế kỷ, chỗ kia nó gục trước giờ cơm trưa.
Con số còn thiếu trong phương trình
Một đòn tấn công vét cạn là phép tính số học tầm thường: số ứng viên phải thử, chia cho số ứng viên thử được mỗi giây. Thừa số thứ nhất phụ thuộc vào mật khẩu của bạn — độ dài, bộ ký tự, chuyện nó có nằm trong từ điển hay không —. Thừa số thứ hai tuyệt đối chẳng liên quan gì tới bạn.
Thừa số thứ hai phụ thuộc hai thứ: phần cứng của kẻ tấn công và, trên hết, cái hàm mà trang web đã dùng để biến mật khẩu của bạn thành mớ ký tự lổn nhổn nằm trong bảng người dùng của họ. Hàm ấy gọi là hash, và không phải hàm nào cũng tốn công tính như nhau.
MD5 và SHA-1 được thiết kế để chạy nhanh. Đó là một ưu điểm: chúng là hàm băm đa dụng, sinh ra để tóm tắt thông điệp và kiểm tra tính toàn vẹn, mà ở việc đó thì thứ bạn muốn là xử lý xong một gigabyte trước khi kịp đứng dậy pha ấm trà. Khi ai đó đem chúng ra cất mật khẩu, ưu điểm ấy hóa thành vấn đề. Một hàm bạn tính được hàng triệu lần mỗi giây là một hàm mà kẻ tấn công cũng tính được hàng triệu lần mỗi giây — và hắn có card đồ họa, lại có nguyên cả cuối tuần.
bcrypt và Argon2 được thiết kế với mục tiêu ngược lại. Chúng chậm một cách cố ý, và — đây mới là chỗ tinh tế — chậm ở mức điều chỉnh được. Niels Provos và David Mazières giới thiệu bcrypt năm 1999 với một cái tựa nói lên tất cả: A Future-Adaptable Password Scheme. Ý tưởng là hàm ấy có thể được làm cho đắt đỏ hơn theo năm tháng, đúng nhịp phần cứng ngày một rẻ đi. Argon2, vô địch Password Hashing Competition năm 2015, thêm một vòng nữa: nó không chỉ tốn thời gian, nó còn tốn bộ nhớ, thứ mà GPU có sẵn ít rộng rãi hơn nhiều.
Giữa một hàm băm nhanh và một hàm băm chậm được cấu hình tử tế không có khác biệt tính bằng phần trăm. Có khác biệt tính bằng bậc độ lớn. Rất nhiều bậc.
Benchmark có thật, và ai cũng xem được
Chẳng có gì ở đây là suy đoán. Hashcat, công cụ mà nửa thế giới dùng để bẻ mật khẩu — kể cả phe tử tế —, có sẵn một chế độ benchmark mà ai cũng chạy được trên máy mình, và nó đo, từng thuật toán một, mỗi giây tính được bao nhiêu lần. Cứ mỗi lần có GPU mới ra lò, cộng đồng lại công bố những bảng ấy.
Điều thú vị ở những bảng đó không phải là con số cụ thể nào — con số ấy còn hết hạn theo từng thế hệ phần cứng — mà là khoảng cách giữa các dòng. Bạn sắp danh sách theo tốc độ và thấy MD5 nằm trên cùng, ở một hành tinh của riêng nó. Bạn kéo xuống, kéo mãi, và tận đáy bảng là bcrypt với Argon2, với những con số chẳng giống chút nào. Vẫn là mật khẩu ấy. Vẫn là cái GPU ấy. Thứ duy nhất thay đổi là trang web đã quyết định cất nó ra sao.
Vì thế «ba triệu năm» mà không nói chống lại hàm băm nào thì là tiếp thị, không phải một phép đo. Nó giống như quảng cáo rằng xe của bạn chạy sáu tiếng là tới, mà không nhắc tới điểm đến.
Offline và online: hai thế giới không chạm vào nhau
Có một phân biệt thứ hai mà gần như không ai giải thích, và nó làm thay đổi kết quả một cách tàn bạo không kém.
Trong một đòn tấn công online, kẻ tấn công thử mật khẩu ngay trên biểu mẫu đăng nhập, như một người dùng bình thường. Nhịp độ không do phần cứng của hắn định đoạt: máy chủ định đoạt. Có thể có giới hạn số lần thử, khóa tạm thời, một cái captcha, độ trễ giữa các yêu cầu, cảnh báo khi phát hiện một nghìn lần sai từ cùng một địa chỉ. Trước một trang được phòng thủ tử tế, tấn công online là chuyện chậm chạp, ồn ào và khá ngớ ngẩn. Phép tính bất lợi cho kẻ tấn công tới mức vét cạn thuần túy gần như chẳng ai buồn thử: người ta đem đúng bốn cái mật khẩu muôn thuở thử vào hàng triệu tài khoản, mà đó lại là một trò khác.
Trong một đòn tấn công offline, kẻ tấn công đã có bản kết xuất cơ sở dữ liệu trong tay. Hắn mang về nhà. Ở đó không có máy chủ, không có giới hạn số lần thử, không có ai nhìn ngó: chỉ có mấy cái card đồ họa của hắn và hóa đơn tiền điện của hắn. Hắn có thể thử hàng tháng trời mà chẳng ai hay, và tự hắn sẽ biết mình đã trúng, bằng cách so các hash với nhau. Đây chính là chỗ hàm băm quyết định tất cả, bởi hàm băm đúng nghĩa đen là thứ duy nhất cản được hắn.
Và cũng nên thành thật về xác suất: kịch bản offline chẳng có gì lạ lùng. Nó xảy ra mỗi lần một cơ sở dữ liệu bị rò rỉ. Khi LinkedIn đánh mất cơ sở dữ liệu của mình năm 2012, phân tích bản kết xuất bị rò cho thấy họ cất mật khẩu bằng SHA-1 không có muối: một hàm băm nhanh, lại thiếu luôn cái thành phần ngăn người ta tính sẵn bảng tra. Chuyện bấy nhiêu mật khẩu bị bẻ, và bẻ nhanh đến thế, không chỉ vì người dùng chọn dở. Trên hết, đó là một quyết định kỹ thuật mà không người dùng nào từng nhìn thấy.
Chúng tôi làm gì ở đây, và vì sao chúng tôi nói ra
Công cụ kiểm tra của chúng tôi giả định 10¹² lần thử mỗi giây, offline, chống lại một hàm băm nhanh. Điều đó được ghi ngay trên trang, ngay dưới kết quả, và không phải để minh bạch cho đẹp: thiếu dữ kiện ấy, con số thời gian hiện ra cho bạn chẳng có nghĩa gì.
Đó là trường hợp xấu một cách cố ý. Chúng tôi giả định cơ sở dữ liệu đã bị rò rồi, kẻ tấn công có phần cứng nghiêm túc, trang web đã cất mật khẩu của bạn theo cách tệ nhất trong những cách còn hợp lý, và hắn còn biết luôn bộ ký tự lẫn độ dài của bạn. Nếu trang web dùng bcrypt được cấu hình tử tế, con số thật sẽ nhảy lên nhiều bậc độ lớn và mật khẩu của bạn trụ được lâu hơn rất nhiều so với những gì chúng tôi nói.
Chúng tôi thà sai về phía đó. Một công cụ kiểm tra chuyên khen bạn thật ra đang tự khen chính nó.
Kết luận khó nghe
Mật khẩu của bạn không có một thời gian bị bẻ. Nó có một thời gian bị bẻ cho từng nơi mà bạn đã dùng nó, và thời gian ấy do những người bạn không quen ấn định, theo những tiêu chí họ không công bố.
Từ đó suy ra hai điều, vẫn là hai điều muôn thuở. Thứ nhất: vì bạn không kiểm soát được hàm băm, hãy kiểm soát entropy, tức là nửa phương trình đúng là của bạn — chính vì thế trình tạo mật khẩu cho bạn xem số bit chứ không phải một cái phần trăm dễ thương —. Thứ hai, và quan trọng hơn: nếu mỗi nơi một mật khẩu riêng, thì cái nơi cất nó bằng MD5 chỉ có thể đem tặng đúng mật khẩu của nơi đó.
Bởi mắt xích yếu không phải là mật khẩu của bạn. Là cái nơi tệ nhất mà bạn từng gõ nó vào.
Nguồn: benchmark công khai của hashcat (hashcat -b), tra cứu được và tái lập được
· N. Provos và D. Mazières, «A Future-Adaptable Password Scheme», USENIX, 1999 ·
Password Hashing Competition, do Argon2 giành chiến thắng năm 2015 · mô hình mối đe
dọa được công bố trong công cụ kiểm tra của password.es: 10¹² lần thử/giây, offline,
hàm băm nhanh · vụ rò rỉ LinkedIn năm 2012: công ty đã xác nhận vụ rò rỉ, và việc
dùng SHA-1 không muối được xác định khi phân tích bản kết xuất được công bố.