Hướng dẫn dùng $1$ hash trong PHP

Facade Hash của Laravel cung cấp hashing Bcrypt và hashing Argon2 để lưu trữ mật khẩu của người dùng. Nếu bạn đang sử dụng các class LoginControllerRegisterController mà đi kèm với application Laravel, thì mặc định nó sẽ sử dụng Bcrypt để đăng ký và authentication cho bạn.

{tip} Bcrypt là một lựa chọn tuyệt vời để hashing mật khẩu vì "work factor" của nó có thể điều chỉnh được, điều đó có nghĩa là thời gian cần thiết để tạo ra một chuỗi hash có thể tăng lên khi sức mạnh phần cứng tăng lên.

Cấu hình

Driver hashing mặc định cho ứng dụng của bạn sẽ được cấu hình trong file cấu hình config/hashing.php. Hiện tại có hai driver được hỗ trợ: Bcrypt và Argon2 (Argon2i và biến thể Argon2id).

{note} Driver Argon2i yêu cầu PHP 7.2.0 hoặc hơn và Driver Argon2id yêu cầu PHP 7.3.0 hoặc hơn.

Cách dùng cơ bản

Bạn có thể hash một mật khẩu bằng cách gọi phương thức make trên facade Hash:

user()->fill([
            'password' => Hash::make($request->newPassword)
        ])->save();
    }
}

Adjusting The Bcrypt Work Factor

Nếu bạn đang thuật toán Bcrypt, thì phương thức make cũng cho phép bạn quản lý work factor của thuật toán bcrypt hashing bằng cách sử dụng tùy chọn

$hashed = Hash::make('password', [
    'rounds' => 12,
]);
2; tuy nhiên, giá trị mặc định được chấp nhận cho hầu hết các application:

$hashed = Hash::make('password', [
    'rounds' => 12,
]);

Adjusting The Argon2 Work Factor

Nếu bạn đang sử dụng thuật toán Argon2, phương thức make cho phép bạn quản lý work factor của thuật toán bằng cách sử dụng các tùy chọn

$hashed = Hash::make('password', [
    'rounds' => 12,
]);
4,
$hashed = Hash::make('password', [
    'rounds' => 12,
]);
5, and
$hashed = Hash::make('password', [
    'rounds' => 12,
]);
6; tuy nhiên, giá trị mặc định được chấp nhận cho hầu hết các application:

$hashed = Hash::make('password', [
    'memory' => 1024,
    'time' => 2,
    'threads' => 2,
]);

{tip} Để biết thêm thông tin về các tùy chọn này, hãy xem tài liệu PHP chính thức.

Verifying A Password Against A Hash

Phương thức

$hashed = Hash::make('password', [
    'rounds' => 12,
]);
7 cho phép bạn xác minh một chuỗi plain-text có tương ứng với một chuỗi đã được hash hay không. Tuy nhiên, nếu bạn đang sử dụng LoginController đi kèm với Laravel, có lẽ bạn sẽ không cần phải sử dụng trực tiếp phương thức này, vì controller này đã tự động gọi phương thức đó:

if (Hash::check('plain-text', $hashedPassword)) {
    // The passwords match...
}

Checking If A Password Needs To Be Rehashed

Hàm

$hashed = Hash::make('password', [
    'rounds' => 12,
]);
9 cho phép bạn kiểm tra xem work factor đã bị thay đổi kể từ sau khi mật khẩu được hash hay chưa:

Nếu bạn là người quản trị hệ thống Linux thường xuyên thì việc login/logout vào hệ thống là điều mặc định hiển nhiên. Trên màn hình đăng nhập, Linux yêu cầu bạn nhập username/password, nếu bạn nhập chính xác thì bạn đăng nhập thành công vào hệ thống. Vậy điều gì đã xảy ra khi bạn nhập username/password, Linux xử lý dữ liệu đó như thế nào? mật khẩu người dùng lưu ở đâu? cơ chế xác thực như thế nào?

Trong bài viết này, tôi tập trung vào tìm hiểu cách linux lưu trữ mật khẩu người dùng.

Trong Linux, file /etc/passwd là file lưu thông tin user của hệ thống, khi bạn tạo một user mới thì linux sẽ add thêm 1 bản ghi mới vào file này. Bạn dùng lệnh để show quyền truy cập file này thì thấy file này có 1 đặc điểm là tất cả người dùng trong hệ thống đều có thể đọc được (‘r’).

[root@localhost ~]# ll /etc/passwd

-rw-r--r-- 1 root root 1373 Apr  1 13:50 /etc/passwd

Điều này khá nhạy cảm vì thông tin user sẽ bị phơi bày trước bất kỳ user nào trong hệ thống. Tuy nhiên thuộc tính ‘r’ là cần thiết vì một số ứng dụng và tool hệ thống cần đọc file này thì mới chạy chính xác. Giả sử, tôi thay đổi quyền truy cập file này để chỉ có ‘root’ mới có quyền đọc.

[root@localhost ~]# chmod 600 /etc/passwd

[root@localhost ~]# ll /etc/passwd

-rw------- 1 root root 1373 Apr  1 13:50 /etc/passwd

Bây giờ, điều gì sẽ xảy ra khi tôi chuyển sang một user thường có sẵn trên hệ thống:

root@localhost ~]# su - mario

id: cannot findname foruser ID 500

id: cannot findname foruser ID 500

[I have no name!@localhost ~]$

Oh, tôi không thể thay đổi chuyển sang tài khoản có tên là mario, bới vì nó sẽ không đọc được file /etc/passwd nên không thể lấy thông tin username, home directory..của mario được lưu trữ trong file /etc/passwd.
Nếu để password lưu trữ trong /etc/passwd thì cũng rất nguy hiểm, mặc dù có thể mã hóa mật khẩu bằng 1 thuật toán băm(Vì tất cả user trong hệ thống đều đọc được).

Vì vậy, cần lưu trữ password người dùng trong 1 file mà chỉ ‘root’ mới đọc được. Giải pháp mà Linux đưa ra là bổ xung 1 file tên là /etc/shadow để lưu trữ mật khẩu người dùng. File /etc/shadow này chỉ truy cập được bởi ‘root’.

[root@localhost ~]# ll /etc/shadow

-r-------- 1 root root 897 Apr  1 13:50 /etc/shadow

Bây giờ, thử xem nội dung file /etc/shadow

Hướng dẫn dùng $1$ hash trong PHP

[root@localhost ~]# cat /etc/shadow

mario:$1$0XJ4dcSP$wpBqBzQSmIppMPEjeYP8K/:16161:0:99999:7:::

  1. 1. Trường đầu tiên, đó chính là username mario

2. Trường thứ 2 đó là trường password đã được mã hóa $1$0XJ4dcSP$wpBqBzQSmIppMPEjeYP8K/. Đây chính xác là trường tôi cần quan tâm và cần khai thác ở bài post này

Nội dung password đã được mã hóa $1$0XJ4dcSP$wpBqBzQSmIppMPEjeYP8K/ có ý nghĩa gì?

- Trường đầu tiên, cho biết thuật toán sử dụng để băm(trong ví dụ này là 1 – MD5 hashing algorithm)

 $1 = MD5 hashing algorithm.

 $2 = Blowfish Algorithm is in use.

 $2a = eksblowfish Algorithm

 $5 = SHA-256 Algorithm

 $6 = SHA-512 Algorithm

- Trường thứ 2 là một chuỗi dữ liệu ngẫu nhiên(random data hay còn gọi là salt) được sinh ra để kết hợp với mật khẩu người dùng(user password), để tăng sức mạnh băm(trong ví dụ này là 0XJ4dcSP)

- Trường thứ 3 là giá trị băm của salt + user password(trong ví dụ này là wpBqBzQSmIppMPEjeYP8K/)

Khi bạn login vào hệ thống, bạn nhập user/password. Hệ thống sẽ sử dụng giá trị salt của user + password mà bạn nhập vào để tạo ra 1 chuỗi mã hóa. Nếu chuỗi mã hóa này trùng với chuỗi mã hóa trong file /etc/shadow thì user login thành công.