Mã hóa mật khẩu thế nào để không bị hack
White

uendno viết ngày 03/06/2017

alt text

Thông thường thì việc mã hóa mật khẩu người dùng là công việc hết sức nhẹ nhàng do các ngôn ngữ lập trình và các framework ngày nay mà anh em lập trình viên hay sử dụng đều hỗ trợ sẵn những hàm mã hóa rất dễ sử dụng. Tuy nhiên, tưởng đơn giản mà lại không đơn giản, đây là vấn đề mà chúng ta dễ mắc những sai lầm trong bảo mật nghiêm trọng nhất.

Theo kinh nghiệm cá nhân của mình thì có một số cách sau để mã hóa và lưu trữ mật khẩu người dùng tăng dần theo cấp độ bảo mật:

  • C1: Lưu luôn mật khẩu vào database, không cần mã hóa gì hết
  • C2: Mã hóa bằng các thuật toán hasing như MD5, SHA256,... rồi lưu đoạn hash vào database. Khi người dùng login thì hash đoạn password mà người dùng nhập rồi so sánh với đoạn hash trong database
  • C3: Tương tự như cách trên nhưng loằng ngoằng hơn ở chỗ sử dụng chồng chéo nhiều thuật toán hashing hoặc hash những đoạn string đại loại như password+username thay vì chỉ đơn thuần là hash mỗi password
  • C4: Generate ra 1 đoạn salt ngẫu nhiên rồi hash tất cả password của user với cùng 1 salt. Tất nhiên là salt phải được lưu lại để kiểm tra
  • C5: Lần này là mỗi một password sẽ được hash với 1 salt khác nhau. Salt này chỉ cần đảm bảo là unique cho từng user là đủ, không cần bí mật. Mục đích của nó chủ yếu là để làm chậm quá trình hack của hacker. Cụ thể ra sao thì anh em xem tiếp phần sau của bài viết.
  • C6: Dùng bcrypt. Về nguyên lí là giống như C5 nhưng độ bảo mật của salt và đoạn mã được sinh ra là cao hơn bằng cách sử dụng working factor cao.

Để tìm hiểu tại sao cách mã hóa và lưu trữ mật khẩu này lại bảo mật hơn cách kia thì chúng ta cần tìm hiểu những cách thức mà hacker sẽ hack để ăn cắp được tài khoản người dùng (hoặc admin)

  • Đối với những hệ thống bảo mật lỏng lẻo như C1 ở trên, 96.69% khả năng là sẽ bị ăn cắp toàn bộ tài khoản người dùng. Thực tế cho thấy database lưu trữ tài khoản người dùng là mục tiêu số 1 của các hacker và thường hay bị hack nhất. Một khi đã đọc được mật khẩu của người dùng thì ngoài sử dụng để thực hiện hành vi xấu trên hệ thống hiện tại, chúng có thể thử với những hệ thống khác do nhiều người có thói quen sử dụng chung 1 mật khẩu cho nhiều hệ thống
  • Bruteforce: Đây là phương pháp sẽ tìm mọi cách kết hợp của các kí tự và thử với từng password một. Về nguyên lí thì cách này sẽ luôn luôn tìm ra mật khẩu chính xác, kể cả có được bảo mật ở mức cao nhất. Tuy nhiên, những cách mã hóa có độ bảo mật càng cao sẽ làm cho hacker mất càng nhiều thời gian hơn. Cụ thể, đối với C2 việc phải hash mật khẩu dự đoán rồi mới so sánh với đoạn hash ăn cắp được từ database sẽ mất thời gian hơn (rất nhiều) so với tấn công vào hệ thống như C1 (trường hợp không ăn cắp được DB). Ở C3C4 nếu hacker tấn công được vào mã nguồn của hệ thống và biết được phương pháp hash hoặc salt dùng chung thì thời gian để hack sẽ không khác C2 là mấy. Đối với cách bảo mật như C5C6 thì gần như là không thể hack được vì thời gian để sinh ra kết hơp giữa salt và password hợp lệ là lâu hoặc quá lâu, có thể mất vài chục, vài trăm năm tùy độ phức tạp của salt.
  • Dictionary: là một cách tiết kiệm thời gian hơn nhưng khả năng tìm thấy mật khẩu đúng sẽ không còn là 100% như bruteforce nữa. Bằng cách tổng hợp tất cả các mật khẩu thường được dùng nhất lại thành 1 file, hacker chỉ cần mã hóa từng mật khẩu một để so sánh. Cách này thực hiện được khả tốt với những trường hợp từ C1 đến C4. Tuy nhiên với C5C6 thì việc hack là không thể (không thể có 1 dictionary cho các salt được). Nếu ở đây kết hợp với bruteforce cho từng password một để tìm ra salt chính xác thì cũng sẽ gần như bất khả thi như cách trên vì giới hạn về mặt thời gian. Lưu ý là từ các cách hack từ đây tở về sau sẽ hiệu quả với trường hợp cần hack toàn bộ user có trong database thay vì chỉ 1 user duy nhất.
  • Lookup table: Tương tự diconary nhưng sẽ tính trước các đoạn mã hóa. Cách này hacker sẽ tốn nhiều dung lượng để lưu trữ hơn rất nhiều so với các cách trên. Tất nhiên là chỉ hoạt động đối với những cách từ C1 đến C4. Salt ngẫu nhiên là không thể tính trước. Vì thế, mặc dù có lấy được Database, biết được salt của từng user thì bảng mà hacker đã chuẩn bị sẵn vẫn vô dụng. Lúc này muốn hack thì lại quay về bruteforce từng password một với điều kiện là hacker có thời gian vài chục năm để hack...
  • Reverse lookup table: Gần giống với lookup table, nhưng thay vì tính trước các đoạn mã hóa, reverse loopup table sẽ chỉ lưu xem đoạn hash nào ứng với những user nào, rồi sử dụng brutefource hoặc dictionary để tấn thử crack từng hash một. Nhìn chung cách này sẽ vẫn chỉ hoạt động với C1 đến C4 và phù hợp với trường hợp nhiều user có chung mật khẩu.
  • Rainbow: Tương tự lookup table nhưng áp dụng những kĩ thuật tính toán cao siêu hơn (cái này mình chịu, anh em nên tham khảo wiki) để đánh đổi tốc độ lấy dung lượng lưu trữ ít hơn. Và mặc dù đây là cách hack cao siêu nhất nhưng đối với C5C6 thì cũng đành bó tay như lookup table.

Vậy tóm lại, trong mọi trường hợp, sử dụng bcrypt vẫn là an toàn nhất và cần ít não để nghĩ nhất, dù cho thời gian để kiểm tra mật khẩu đúng khi user đăng nhập có mất thời gian hơn là MD5, SHA256,...

Trần Việt Thắng 03-06-2017

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

uendno

1 bài viết.
0 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
1 bài viết.
0 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!