【Back to basics】Lưu password của user như thế nào?

【Back to basics】Lưu password của user như thế nào?

Thử dùng Envoy của Laravel để viết script deploy cho ứng dụng web
Laravel – Tận dụng Traits cho Model
LARAVEL bạn đã viết đúng?

Bảo mật password của user là 1 trong những mảng quan trọng nhất trong 1 Web Application. Hầu hết các Web mà bạn tạo ra đều yêu cầu cơ chế login – đăng nhập. Không may, tạo ra cơ chế đủ tốt để lưu password 1 cách an toàn không phải là việc dễ. Hãy thử tìm hiểu vấn đề này xem nhé.

Khi bạn mới chập chững vào nghề lập trình web, thường những bài tập đầu tiên sẽ là: tạo 1 form cho phép user đăng ký và login. Để implement việc này, bạn sẽ thiết kế 1 DB gồm 4 trường: ID, login (username), email, và password.
Luồng hoạt động sẽ như hình bên dưới

Rất đơn giản phải không? Tuy nhiên cách implement này tồn tại 1 điểu yếu chết người. Giả sử DB của bạn bị hack, và dữ liệu người dùng bị lộ thì sao?
Bị lộ thì trông sẽ như thế này này

Và bạn cho rằng chả có vấn đề gì đâu, website của bạn đâu có gì liên quan tới tiền mà lo. Ấy, vấn đề là hầu hết người dùng đều dùng chung combo email + password cho nhiều dịch vụ khác, ví dụ như Youtube, Facebook… Tèn ten, hacker đơn giản là dùng dữ liệu lấy được từ website của bạn và login thử vào các trang web khác là xong.

Ta có thể cải thiện điều này bằng cách

Mã hoá password lại

Cách này có vẻ bảo mật hơn 1 chút, vì DB của bạn trông sẽ như thế này

Hacker sẽ gặp khó khăn trong việc đọc password vì password đã được mã hoá, không còn “trần truồng” nữa. Tuy nhiên hacker có thể tìm cách giải mã password đó. Ví dụ như tự tạo vài account và đặt password, sau đó theo dõi xem password sau mã hoá trông như thế nào.

Ta có thể nâng cấp thụât toán trên bằng cách

Hashing

Để tránh việc bị giải mã, ta sẽ sử dụng mã hoá một chiều là loại mã hoá không thể giải mã được.

Giải thụât mã hoá thường được sử dụng là MD5, SHA1, SHA2…Cách làm này đã giảm thiếu khá nhiều khả năng hacker lấy được raw password của user.
Tuy nhiên vẫn tồn tại đó 1 lỗ hổng: do các thuật toán mã hoá quá phổ biến, được nhiều người sử dụng (hàm md5 được support sẵn trong PHP, chẳng hạn) nên chuỗi password mã hoá cũng dần dễ bị suy ngược hơn. Bạn có thể Google cụm “e00cf25ad42683b3df678c61f42c6bda”, kết quả trả về sẽ là “admin1”. Hoặc bạn có thể vào đây để kiểm tra. Những trang web như HashToolKit cho phép bạn gõ 1 mã hash bất kỳ vào, trả về raw trước mã hoá của cụm mã đó.

Vậy phải làm thế nào?

Salting

Salt là 1 chuỗi ngẫu nhiên được cộng thêm vào raw password trước khi đem đi mã hoá. Bằng cách này bạn giảm thiểu khả năng hacker suy ngược từ chuỗi password đã mã hoá về raw password ban đầu. Dĩ nhiên bạn sẽ giấu đoạn salt của bạn ở 1 nơi kín đáo. Có 2 kiểu salt phổ biến
– Fixed salt: sử dụng chung 1 đoạn salt cho tất cả các password. Kiểu này vẫn để ngỏ khả năng 2 đoạn password giống nhau sinh ra đoạn mã hoá giống nhau. Hacker nếu chiếm được quyền điều khiển DB có thể dùng cách copy đoạn mã hoá password của tài khoản hacker, ghi vào field password mã hoá của 1 user nào đó. Bằng cách này tuy hacker không biết được raw password, nhưng vẫn có thể login được vào hệ thống của bạn.
– Dynamic salt: sinh ra salt riêng biệt cho mỗi user. Vì thế cho dù 2 đoạn password giống nhau, kết quả mã hoá sinh ra sẽ là khác nhau. Tuy nhiên bạn cần lưu lại đoạn salt để dùng lại khi user đăng nhập.

Tối ưu hoá

  • Bạn có thể áp dụng mã hoá chồng với đoạn password đã mã hoá. Bằng cách này hacker sẽ khó đoán được raw password hơn
  • Bạn có thể kết hợp cả 2 cách fixed salt và dynamic salt để tạo ra phương thức an toàn hơn
  • Bạn nên cài đặt cơ chế limit login để tránh bị brute force attack. Cài đặt thêm CAPTCHA cũng là 1 ý kiến không tồi

Và cách tốt nhất

Cách tốt nhất để giảm thiểu nỗi lo xử lý password là… hãy để người khác lo giùm bạn. Bạn có thể cài đặt Facebook Login/ Google Login… Điều này vừa giảm nỗi lo cho bạn, vừa giúp user không mất công tạo tài khoản hay phải nhớ 1 password mới.
Text of Relipa cũng đang áp dụng cách này.

Bài viết có tham khảo nội dung ở JSCrambler

COMMENTS