Cách hash và xác minh mật khẩu trong Node.js bằng bcrypt

Nếu phải quản lý mật khẩu của người dùng, bạn cần đảm bảo chúng an toàn. Thư viện bcrypt sẽ giúp bạn thực hiện quá trình này dễ dàng hơn.

Hash mật khẩu

Một trong số những cách tốt nhất để lưu trữ mật khẩu an toàn là salt và hash chúng. Salt và hash chuyển đổi một mật khẩu đơn giản thành một giá trị duy nhất mà khó đảo ngược. Thư viện bcrypt cho phép bạn hash và salt mật khẩu trong Node.js ít tốn công sức nhất có thể.

Hash mật khẩu là gì?

Hash mật khẩu có nghĩa là chuyển một mật khẩu dưới dạng văn bản thuần túy qua một thuật toán hash để tạo giá trị duy nhất. Giá trị này gọi là hash. Một số ví dụ của thuật toán hash là bcrypt, scrypt và SHA.

Một trong số thuộc tính chính của thuật toán hash tốt là nó tạo cùng một đầu ra cho cùng một đầu vào. Khả năng dự đoán này tạo lỗ hổng khiến hash dễ bị tấn công. Tin tặc có thể tính toán trước giá trị hash cho nhiều đầu vào thường được sử dụng, rồi so sánh chúng với các giá trị hash trong giá trị mục tiêu. Bạn có thể giảm thiểu lỗ hổng này bằng cách dùng salt.

Salt mật khẩu là gì?

Salt mật khẩu bổ sung một chuỗi ngẫu nhiên vào password trước khi hash nó. Bằng cách này, mỗi lần tạo hash đều luôn khác nhau. Ngay cả khi một hacker lấy được mật khẩu đã hash, họ đều mất thời gian đáng kể để khám phá mật khẩu ban đầu đã tạo ra mật khẩu đó.

Cách dùng Bcrypt để hash và xác minh mật khẩu

bcrypt là một mô đun npm, đơn giản hóa cách bạn hash mật khẩu trong Node.js. Để dùng nó, hãy làm theo những bước dưới đây:

Bước 1: Cài đặt Bcrypt

Cài đặt bcrypt bằng cách chạy các lệnh terminal sau.

Dùng npm:

npm install bcrypt

Dùng yarn:

yarn add bcrypt

Bước 2: Nhập Bcrypt

Ở phía trên cùng của file JavaScript, nhập bcrypt.

const bcrypt = require("bcrypt")

Bước 3: Tạo Salt

Gọi hàm bcrypt.genSalt() để tạo một salt. Phương thức này chấp nhận một giá trị số nguyên là yếu tố chi phí xác định thời gian cần thiết để hash mật khẩu. Yếu tố chi phí càng cao, thuật toán càng mất nhiều thời gian và càng khó đảo ngược được mật khẩu được mã hóa.

Một giá trị tuyệt vời vừa đủ cao để bảo vệ mật khẩu nhưng cũng đủ thấp để làm chậm quá trình này. Nó thường nằm trong phạm vi từ 5 tới 15. Ví dụ trong bài viết dùng 10.

bcrypt.genSalt(10, (err, salt) => {
    // use salt to hash password
})

Bước 4: Hash mật khẩu

Trong hàm bcrypt.genSalt, chuyển mật khẩu đơn giản và salt đã được tạo tới hàm bcrypt.hash() để hash mật khẩu.

bcrypt.genSalt(10, (err, salt) => {
    bcrypt.hash(plaintextPassword, salt, function(err, hash) {
        // Store hash in the database
    });
})

Sau khi tạo hash, lưu trữ nó trong database. Bạn sẽ dùng nó để xác minh một mật khẩu và xác thực người dùng đang cố gắng đăng nhập.

bcrypt.hash(plaintextPassword, 10, function(err, hash) {
    // store hash in the database
});

Bước 5: So sánh mật khẩu bằng bcrypt

Để xác thực người dùng, bạn cần so sánh mật khẩu họ cung cấp với mật khẩu trong cơ sở dữ liệu bằng hàm bcrypt.compare(). Hàm này chấp nhận mật khẩu văn bản thuần túy và hàm hash mà bạn đã lưu trữ, cùng với hàm callback. Hàm gọi lại này cung cấp một đối tượng chứa bất kỳ lỗi nào đã xảy ra và kết quả tổng thể từ quá trình so sánh. Nếu mật khẩu khớp với hàm hash, kết quả là đúng.

bcrypt.compare(plaintextPassword, hash, function(err, result) {
    if (result) {
        // password is valid
    }
});

Dùng Async/Await

Bạn có thể mã hóa mật khẩu trong Node.js với Bcrypt bằng async/await như sau:

async function hashPassword(plaintextPassword) {
    const hash = await bcrypt.hash(plaintextPassword, 10);
    // Chứa hash trong database
}
 
// so sánh mật khẩu
async function comparePassword(plaintextPassword, hash) {
    const result = await bcrypt.compare(plaintextPassword, hash);
    return result;
}

Dùng Promise

Thư viện bcrypt cũng hỗ trợ sử dụng promise. Ví dụ, đây là một hàm hash mật khẩu bằng cách dùng khối then...catch.

function hashPassword(plaintextPassword) {
    bcrypt.hash(plaintextPassword, 10)
        .then(hash => {
            // Store hash in the database
        })
        .catch(err => {
            console.log(err)
        })
}

Tương tự như vậy, chức năng này so sánh mật khẩu đơn giản từ người dùng với mật khẩu đã hash bằng promise.

function comparePassword(plaintextPassword, hash) {
   bcrypt.compare(plaintextPassword, hash)
       .then(result => {
           return result
       })
       .catch(err => {
           console.log(err)
       })
}

Bạn có thể sử dụng thư viện Bcrypt để hash và xác minh mật khẩu trong Node.js. Hash mật khẩu giảm thiểu khả năng tội phạm mạng truy cập mật khẩu đơn giản và sử dụng chúng để truy cập dữ liệu hoặc dịch vụ nhạy cảm.

Salt mật khẩu đã hash của bạn làm cho chúng thậm chí còn an toàn hơn. Ngoài việc hash, hãy luôn xác thực độ mạnh của mật khẩu như một biện pháp bảo mật bổ sung.

Thứ Sáu, 14/04/2023 09:30
51 👨 1.652
0 Bình luận
Sắp xếp theo