+6

Cơ bản về mã hóa mật khẩu

MỤC LỤC

  1. Tại sau ta cần phải mã hóa mật khẩu?
  2. Cơ bản về băm mật khẩu
  3. Giới thiệu về Bcrypt

I. Tại sao ta cần phải mã hóa mật khẩu?

Hẳn mọi lập trình viên đều không lạ lẫm gì với việc mã hóa mật khẩu. Nó là một bước quan trọng cho phép ta đảm bảo thông tin người dùng được an toàn ngay cả trong tình huống cơ sở dữ liệu của chúng ta bị tổn hại. Đã có rất nhiều tình huống ứng dụng web bị lộ thông tin người dùng. Điều này sẽ còn đáng lo ngại hơn nữa nếu như thông tin mật khẩu của chúng ta không được mã hóa một cách cẩn thận. Có không ít người sử dụng cùng một mật khẩu cho hầu hết các tài khoản của họ. Để lộ một mật khẩu và tất cả các tài khoản khác đều bị nguy cơ đánh cắp. Vì vậy ta không bao giờ nên lưu trữ mật khẩu dưới dạng một đoạn text đơn thuần.

Một trong những cách phổ biến nhất để giải quyết vấn đề này là thực hiện băm mật khẩu.

II. Cơ bản về băm mật khẩu

Hashing

Băm mật khẩu là một cách tiếp cận khá phổ biến trong việc giải quyết vấn đề bảo mật mật khẩu. Hàm băm là hàm một chiều cho phép ta thực hiện biến đổi mật khẩu ban đầu thành một chuỗi thể hiện cho nó và không thể giải mã ngược. Mỗi giá trị băm sẽ chỉ tương ứng với một mật khẩu. Chúng ta sẽ lưu vào cơ sở dữ liệu giá trị kết quả của hàm băm. Khi thực hiện xác thực người dùng, hệ thống sẽ thực hiện mã hóa đầu vào của người dùng, so sánh với cơ sở dữ liệu để kiểm tra và đưa ra kết quả.

VD:
"HelloWorld" sau khi băm sử dụng thuật toán băm md5 sẽ cho kết quả giống như sau "68e109f0f40ca72a15e05cc22786f8e6".

Với công nghệ máy tính hiện nay, việc giải mã hàm băm là điều không thể. Tuy nhiên, nếu chúng ta không cẩn thận, vẫn có các cách kẻ giả mạo có thể có được mật khẩu nếu hắn ta nắm trong tay mã hash. Hai cách thức tấn công phổ biến là:

  • Rainbow table attacks (tấn công sử dụng từ điển mật khẩu được tính toán từ trước) .
  • Brute Force attacks (tấn công thử mọi tình huống có thể).

Để giải quyết vấn đề này ta sẽ đi vào tìm hiểu về SaltingStretching.

Salting

Như đã đề cập ở trên, việc băm mật khẩu đơn thuần là không đủ, để xử lý tấn công tính toán trước ta sử dụng Salt. Salting là hành động thêm vào bên cạnh mật khẩu ban đầu một đoạn dữ liệu trước khi băm.

Salting tuy đơn giản nhưng vô cùng mạnh mẽ. Nó đã nâng độ phức tạp của mật khẩu lên một tầm cao mới do mật khẩu ban đầu đã trở nên dài hơn và đồng nghĩa với đó là độ phức tạp cao hơn rất nhiều. Bằng cách thêm salt, ta đã khiến cho tất cả các cách thức tấn công sử dụng tính toán trước trở nên vô dụng. Mỗi tài khoản người dùng khi tạo sẽ được khởi tạo một dãy salt ngẫu nhiên duy nhất khi đăng ký. Hai tài khoản có cùng mật khẩu sẽ không có chung giá trị băm trả về. Vì nó chỉ được sử dụng để giải quyết vấn đề tính toán trước việc tạo ra một hệ thống riêng để lưu trữ salt là không cần thiết và thông thường ta sẽ lưu trực tiếp trong cùng bảng.

Stretching

Bên cạnh Rainbow table attacks, brute force cũng là một hình thức tấn công khá phổ biến. Nếu việc tính toán không quá phức tạp kẻ tấn công có thể nhanh chóng lắp ghép và thử mọi trường hợp để tìm ra mật khẩu người dùng. Đến đây ta sẽ đi vào tìm hiểu về khái niệm stretching.

Stretching là cách thức để tăng độ phức tạp của thuật toán băm khiến việc brute force qua mọi trường hợp trở nên không khả khi. Để đạt được điều này thông thường ta sẽ lặp quá trình băm hàng ngàn lần. Việc này khiến cho người dùng biết mật khẩu tốn thêm một chút thời gian nhưng sẽ tốn kẻ tấn công gấp rất nhiều lần để tìm ra kết quả. Đối với một mật khẩu an toàn việc brute force để tìm ra chúng là gần như không thể.

III. Bcrypt

Bcrypt là một hàm mã hóa mật khẩu được thiết kế bởi Niels Provos và David Mazières dựa trên các thuật toán mã hóa Blowfish và được giới thiệu lần đầu tại USENIX trong năm 1999. Nó là sự kết hợp của cả ba khái niệm ta vừa tìm hiểu "hashing" "streching" và "salting".

Thông thường một dãy hashing của bcrypt sẽ có dạng như sau:

$[algorithm]$[cost]$[22 characters salt][31 characters hash]

VD: "HelloWorld" sử dụng Bcrypt sẽ cho kết quả

$2y$10$RT2Pnlx7aaG2EDHy8SgdIunndkeiLB.kUTzSdVoKgL2x/TEr1tkZG
|__|__|_____________________|_______________________________|
Alg Cost       Salt                        Hash

Trong đó:
2y: thuật toán băm
10: chi phí (2^10 hay 1024 vòng lặp)
RT2Pnlx7aaG2EDHy8SgdIu: 16-byte (128-bit) salt được encode base64 về 22 kí tự.
nndkeiLB.kUTzSdVoKgL2x/TEr1tkZG: 24-byte (192-bit) mã băm được encode base64 về 31 kí tự.

Vậy với mã hash như trên mật khẩu của chúng ta sẽ chạy tổng cộng 2 mũ 10 lần (1024 vòng lặp) sử dụng salt RT2Pnlx7aaG2EDHy8SgdIu, mật khẩu "HelloWorld" kết hợp với thuật toán mã hóa blowfish $2y$ để cho chúng ta kết quả như trên.

TỔNG KẾT

Vậy qua đây chúng ta đã đi vào tìm hiểu tại sau phải mã hóa mật khẩu, các cách thức tấn công phổ biến, cùng với đó là các cách thức để phòng chống lại nó sử dụng salt và stretching, cuối cùng ta đi vào giới thiệu hàm băm bcrypt để thấy các khái niệm đã nêu trên sử dụng trong thực tế. Đây là bài viết đầu tiên của em trên Viblo, nếu còn gì thiếu sót xin mọi người góp ý.

TÀI LIỆU THAM KHẢO

https://www.usenix.org/legacy/events/usenix99/provos/provos_html/node1.html https://culttt.com/2013/01/21/why-do-you-need-to-salt-and-hash-passwords/ https://www.bmc.com/blogs/salting-stretching-passwords/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí