Note: see the link below for the English version of this article.
https://duongnt.com/strong-password
Dưới đây là yêu cầu về mật khẩu của trang quản lý xuất nhập cảnh Nhật Bản.
Use at least one from each of the alphabet letters, numbers, and signs. The total length must be 8 letters or longer and up to 32 characters.
Tạm dịch:
mật khẩu cần chứa chữ cái, số và ký tự đặc biệt. Chiều dài mật khẩu phải nằm giữa 8 và 32 ký tự.
Yêu cầu này tương đối phức tạp, nhưng nó có thực sự giúp tài khoản của ta được an toàn hơn? Trong bài này, chúng ta sẽ tìm hiểu xem việc yêu cầu mật khẩu phải phức tạp là có lợi hay có hại. Và chúng ta sẽ tìm hiểu xem làm thế nào để tạo được một mật khẩu mạnh mà lại vẫn dễ nhớ.
Biết mình biết người…
Khi tìm hiểu về bất kỳ vấn đề bảo mật nào, điều đầu tiên cần làm là xác định xem ta đang phải đối mặt với những cách tấn công nào. Dưới đây là một số cách hack mật khẩu.
- Lừa người dùng tự tiết lộ mật khẩu, hoặc cài trojan vào thiết bị của họ.
- Tấn công vào hệ thống mà người dùng đăng nhập, từ đó chiếm quyền truy cập hệ thống lưu trữ mật khẩu. Phương pháp này chỉ khả thi nếu mật khẩu được lưu dưới dạng không mã hóa. Đây là một sơ hở lớn, nhưng lại không hiếm gặp trong thực tế.
- Thử các mật khẩu thông dụng xem có trùng với mật khẩu người dùng sử dụng không (tấn công từ điển).
- Thử tất cả các mật khẩu cho đến khi tìm được cái đúng (tấn công vét cạn).
Có thể thấy là với kiểu tấn công thứ nhất, các quy định về mật mã hoàn toàn không giúp ích gì. Với kiểu tấn công thứ hai, nếu mật khẩu của ta bị lưu dưới dạng không mã hóa và dịch vụ ta sử dụng bị hack thì không cũng không còn cách cứu chữa. Tuy nhiên nếu mật khẩu được lưu dưới dạng hash thì hacker cần phải từ hash tìm ngược lại mật khẩu của ta. Bước này khó hay dễ tùy thuộc vào giải thuật hash được sử dụng.
Một card đồ họa (GPU) bình thường có thể thực hiện hàng tỷ hash SHA1 mỗi giây, nhưng tốc độ này giảm xuống còn vài ngàn mỗi giây nếu hash được tạo bằng giải thuật bcrypt. Tất nhiên là hacker sẽ thực hiện tấn công từ điển trước, và chỉ dùng tấn công vét cạn khi không còn cách nào khác. Nếu hash bị lộ thì tốc độ tấn công của hacker chỉ bị hạn chế bởi năng lực tính toán của họ. Còn nếu họ thử tấn công vét cạn vào hệ thống đang hoạt động bình thường thì nhiều khả năng là cuộc tấn công đó sẽ bị phát hiện và ngăn chặn.
Câu hỏi ta cần đặt ra là liệu yêu cầu người dùng đặt mật khẩu phức tạp có giúp giảm nguy cơ khi bị tấn công từ điển hay tấn công vét cạn?.
Vì sao các quy định mật khẩu phức tạp là không mấy hữu ích
Đối với tấn công từ điển, quy định mật khẩu phức tạp có thể khiến chính mật khẩu đó dễ bị hack hơn. Lý do vì hiếm ai muốn tạo và nhớ một mật khẩu dài và phức tạp. Vì thế khi buộc phải làm vậy, họ thường làm một trong hai điều sau.
- Tạo một mật khẩu duy nhất và tái sử dụng cho nhiều hệ thống. Lúc này chỉ cần một hệ thống làm lộ mật khẩu thì tất cả các hệ thống dùng chung mật khẩu đó cũng coi như xong.
- Lấy một mật khẩu thông dụng và thêm một vài ký tự hay số vào cuối. Kết quả là mật khẩu mới nhìn thì có vẻ mạnh, nhưng chỉ cần dùng một đoạn script ngắn là có thể tìm ra được biến thể mới đó.
Vậy nếu ta bắt người dùng thường xuyên đổi mật khẩu thì có giải quyết được vấn đề trên không? Khi phải đổi mật khẩu thường xuyên, người dùng thường thêm một số vào cuối và cộng 1 vào số đó mỗi khi đổi password. Ví dụ, họ sẽ dùng password1/password2/password3
. Những mật khẩu như thế cũng dễ dàng bị đánh bại bởi một đoạn script ngắn. Thực tế là nếu mật khẩu của ta mạnh và không bị tái sử dụng thì không có lý do gì để ta thay nó thường xuyên.
Đối với tấn công vét cạn, vấn đề với phần lớn các quy định mật khẩu là chúng khiến mật khẩu trở nên khó nhớ hơn, trong khi chưa chắc đã khiến máy tính khó mò ra mật khẩu đó. Để hiểu nguyên nhân, ta cần dùng đến khái niệm entropy.
Khái niệm entropy
Trong lý thuyết thông tin, entropy, hay còn gọi là Shannon entropy, được định nghĩa như sau.
The entropy of a random variable is the average level of "information", "surprise", or "uncertainty" inherent in the variable’s possible outcomes.
Đoạn trên nghe có vẻ phức tạp, nhưng ta có thể hiểu đơn giản entropy là đơn vị đo độ ngẫu nhiên của một biến. Khi nói về entropy của một mật khẩu, ta muốn biết việc đoán mò mật khẩu đó khi không có thêm bất kỳ thông tin nào là khó hay dễ.
Ví dụ khi ta tung một đồng xu và thử đoán xem nó sẽ sấp hay ngửa, khả năng để đồng xu sấp hoặc ngửa đều là 50%. Tức là kết quả của ta sẽ là một trong hai khả năng, lúc này ta nói việc tung đồng xu có entropy là log₂(2) == 1 bit. Nếu mật khẩu của ta là một trong X khả năng thì entropy của mật khẩu đó sẽ được tính như sau.
log₂(X)
Khi tính entropy của một mật khẩu, ta không chỉ quan tâm mật khẩu đó dài hay ngắn, phức tạp hay không, mà ta cần xem nó là một trong bao nhiêu khả năng. Ta sẽ thử so sánh hai mật khẩu sau, SnrPpSBVW53
và letmein1989
, cái đầu tiên hoàn toàn ngẫu nhiên và chứa chữ thường, chữ hoa, số. Trong khi đó, mật khẩu thứ hai chỉ là một mật khẩu thường dùng và gắn thêm năm sinh, đây là một cách tạo mật khẩu phổ biến.
Vì có 10 số và bảng chữ cái tiếng Anh có 26 chữ, entropy của mật khẩu thứ nhất được tính là log₂((26 + 26 + 10)¹¹) == 65 bit. Ước lượng entropy cho mật khẩu thứ hai khó hơn. Nhưng nếu ta giả thiết là bên tấn công dùng danh sách 1000 mật khẩu thường dùng nhất (chắc chắn có chứa letmein
), và năm sinh nằm trong khoảng 1900 ~ 2021 (122 năm), thì entropy được tính là log₂(1000×122) == 17 bit.
Ta có thể tạo password với entropy cao mà chỉ dùng chữ cái, hoặc chỉ dùng số, hay thậm chỉ là chỉ dùng 0 và 1, ta chỉ cần để mật khẩu dài hơn. Ví dụ, một mật khẩu chỉ gồm 0 và 1 nhưng dài 128 ký tự sẽ có entropy là log₂(2¹²⁸) == 128 bit.
Dùng entropy để ước lượng thời gian hack mật khẩu
Vì sao ta phải quan tâm tới khái niệm entropy? Đó là vì một mật khẩu có entropy càng cao thì càng khó bị đoán mò trúng. Nếu mật khẩu chỉ có entropy là 8 bit thì tức là nó là một trong 2⁸ == 256 khả năng, và chỉ cần tối đa 256 lần đoán là tìm được mật khẩu đó. Trong thực tế, số lần đoán thường thấp hơn thế, vì chỉ sau 2⁸⁻¹ == 128 lần đoán, xác suất đoán trúng đã là 50%.
Giả sử là hacker đã biết được hash SHA1 của mật khẩu của ta (SHA1 có thể được tính rất nhanh, vì thế ta không nên dùng nó để hash mật khẩu). Ta sẽ tính xem mật khẩu cần có entropy tối thiểu là bao nhiêu để không phải sợ tấn công vét cạn. Nếu một máy tính có thể tính N hash mỗi giây thì nó có thể hack được một mật khẩu với entropy là log₂(N) chỉ sau 1 giây. Nếu ta muốn mật khẩu vẫn an toàn sau T giây thì entropy tối thiểu của mật khẩu đó được tính như sau.
log₂(N) + log₂(T)
Bảng dưới đây ghi lại một số mốc đáng chú ý.
Năng lực tính toán | Tốc độ (Hash/s) | An toàn sau 1s | An toàn sau 1 năm | An toàn sau 100 năm |
---|---|---|---|---|
CPU bình thường | 24,000,000 | 26 bit | 50 bit | 57 bit |
GPU bình thường | 1.14×10¹° | 34 bit | 59 bit | 65 bit |
Mạng lưới Bitcoin network¹ | 1.8×10¹⁷ | 58 bit | 83 bit | 89 bit |
¹: kỷ lục về tốc độ tính toán của toàn mạng lưới Bitcoin là 1.8×10¹⁷ Hash/s, đạt được vào tháng 5/2021.
Entropy của một mật khẩu bình thường
Nếu mật khẩu của ta chỉ vừa đủ đáp ứng yêu cầu của cục xuất nhập cảnh Nhật Bản thì nó sẽ có entropy là bao nhiêu? Mật khẩu đó sẽ dài 8 ký tự, và bao gồm chữ thường, số và ký tự đặc biệt. Ta có 26 chữ cái, 10 con số và khoảng 30 ký tự đặc biệt, tức là tổng cộng mỗi ký tự sẽ có 66 lựa chọn. Với 8 ký tự, mật khẩu của ta là một trong 66⁸ == 3.6×10¹⁴ khả năng, tức là nó có entropy vào khoảng 48 bit. Có thể thấy mật khẩu này không mấy bảo mật, một CPU bình thường có thể tìm được nó sau 49 ngày, còn GPU sẽ tìm được nó sau 70 phút.
Để tăng entropy cho mật khẩu, ta cần tăng số khả năng. Nếu mật khẩu của ta dài 15 ký tự thay vì 8, và nó dùng cả chữ hoa lẫn chữ thường thì số khả năng tăng lên thành 92¹⁵ == 2.86×10²⁹. Tức là entropy sẽ tăng lên thành 97 bit, kể cả ta dùng toàn bộ mạng lưới Bitcoin để tính toán trong 100 năm thì cũng khó hack nổi mật khẩu này.
Tuy nhiên điều kiện ở đây là cả 15 ký tự đều phải được chọn ngẫu nhiên, mật khẩu lúc đó sẽ rất khó nhớ. Như đã thấy trong phần trước, nếu ta lấy một mật khẩu thông dụng như letmein
và thêm vào cuối 7 ký tự cho đủ 15 ký tự thì entropy sẽ bị giảm xuống. Entropy lúc này sẽ phụ thuộc phần lớn vào 7 ký tự mới đó, và chúng chỉ cho talog₂(92⁷) == 45 bit entropy.
Dùng passphrase thay cho mật khẩu
Ta nên dùng passphrase thay cho mật khẩu. Passphrase có dạng câu dài, nhưng nó vẫn dễ nhớ hơn mật khẩu thông thường trong khi lại mạnh hơn. Ta chỉ cần chuẩn bị một danh sách từ (ví dụ như danh sách này của tổ chức EFF) và 5 con xúc xắc. Cách tạo passphrase với 8 từ là như sau.
- Gieo 5 con xúc xắc và xem kết quả là bao nhiêu.
- Ví dụ kết quả là 1-3-6-3-2 thì ta tìm tới từ được đánh số
13632
trong danh sách từ, với danh sách của EFF thì từ đó làbootie
. Đây là từ đầu tiên của passphrase. - Lặp lại 2 bước trên thêm 7 lần nữa (khi viết bài này, tôi quay ra được passphrase là
bootie backlands relieve uselessly negligee tumble impolite pediatric
).
Sau đây ta sẽ thử tính entropy cho passphrase vừa tạo. Vì mỗi từ được chọn ngẫu nhiên trong danh sách chứa 6⁵ == 7776 từ, chúng đều có entropy là log₂(7776) == 12.92 bit. Vì passphrase của ta chứa 8 từ nên entropy tổng cộng sẽ là 8×12.92 == 103 bit. Nếu muốn tăng entropy thêm nữa thì ta chỉ cần thêm một hay nhiều từ vào passphrase. Mỗi từ được thêm vào sẽ tăng entropy thêm 12.92 bit. Lượng entropy này cao hơn nhiều so với entropy của một mật khẩu 15 ký tự, và tôi thấy nhớ passphrase dễ hơn so với việc nhớ một mật khẩu như BH~y/ekYqV@C8nW
.
Kết thúc
Khi sử dụng đúng cách, passphrase giúp ta không còn phải lo lắng về tấn công vét cạn. Để chứng minh điều này, tôi sẽ cho các bạn biết hash MD5 của mật khẩu admin trang blog này.
e56e62623a52f1a69ab5366e1526057b
Mật khẩu của tôi là một passphrase 8 từ, được sinh từ danh sách của tổ chức EFF mà tôi nhắc đến ở trên và sử dụng một con xúc xắc bình thường. MD5 là một hash có tốc độ tính toán rất nhanh, nên tấn công vét cạn hash này còn dễ hơn tấn công hash SHA1. Liệu có ai muốn thử sức không?