Hash Tag Đời: Giải Mã crypto.createHash() Cùng Thầy Creyt!
Nodejs

Hash Tag Đời: Giải Mã crypto.createHash() Cùng Thầy Creyt!

Author

Admin System

@root

Ngày xuất bản

21 Mar, 2026

Lượt xem

2 Lượt

"crypto.createHash()"

Alo alo! Lớp học lập trình của thầy Creyt đây, mấy đứa Gen Z đã sẵn sàng 'quẩy' cùng thầy chưa? Hôm nay, chúng ta sẽ lặn sâu vào một khái niệm mà nghe tên thôi đã thấy 'ngầu' rồi: crypto.createHash() trong Node.js. Nghe thì có vẻ 'hầm hố' nhưng thực ra nó 'dễ như ăn kẹo' nếu mấy đứa chịu khó nghe thầy 'phán' đây.

1. crypto.createHash() là cái quái gì và để làm gì?

Tưởng tượng thế này nhá: crypto.createHash() nó giống như một cái máy xay sinh tố 'siêu cấp vũ trụ' vậy. Mấy đứa ném bất kỳ thứ gì vào – từ một dòng chữ 'Hello World', cả một cuốn tiểu thuyết, hay thậm chí là cả một bộ phim 4K – cái máy này sẽ xay nhuyễn ra và cho ra một 'ly sinh tố' đặc quánh, có kích thước cố định y chang nhau. Dù mấy đứa ném cái gì vào, ly sinh tố cuối cùng vẫn luôn là một ly, không to hơn cũng không bé hơn.

Cái 'ly sinh tố' đặc biệt này chính là hash value (giá trị băm) hay còn gọi là digest. Và nó có mấy đặc điểm 'thần thánh' mà mấy đứa phải nhớ kỹ:

  • Một chiều (One-way): Từ ly sinh tố, mấy đứa KHÔNG THỂ nào biết được ban đầu mình đã ném những nguyên liệu gì vào. Nó giống như 'đã nấu cơm thì không thể hoàn nguyên gạo' vậy. Cái này cực kỳ quan trọng cho bảo mật đấy!
  • Xác định (Deterministic): Nếu mấy đứa ném chính xác những nguyên liệu y hệt nhau vào máy xay, thì lần nào cũng sẽ ra chính xác ly sinh tố y hệt. Không sai một li!
  • Khó đụng hàng (Collision-resistant): Cực kỳ khó, gần như không thể, để tìm ra hai bộ nguyên liệu khác nhau mà lại cho ra cùng một ly sinh tố. Giống như tìm hai người có cùng dấu vân tay vậy – hiếm lắm!

Vậy crypto.createHash() dùng để làm gì? Nó chính là công cụ để tạo ra cái 'dấu vân tay số' (digital fingerprint) độc nhất vô nhị cho bất kỳ dữ liệu nào. Dấu vân tay này giúp chúng ta:

  • Kiểm tra tính toàn vẹn dữ liệu: Dữ liệu có bị sửa đổi trên đường truyền hay không?
  • Lưu trữ mật khẩu an toàn: Thay vì lưu mật khẩu trần trụi (dở hơi!), ta lưu dấu vân tay của nó.
  • Và nhiều thứ 'deep' hơn nữa': Như trong blockchain, chữ ký số, v.v.

2. Code Ví Dụ Minh Hoạ: Hóa ra 'Dễ Ợt'

Trong Node.js, module crypto là 'kho báu' chứa đầy những công cụ mã hóa. createHash() là một trong số đó. Để sử dụng, mấy đứa cần chỉ định 'thuật toán xay' (algorithm) mà mấy đứa muốn dùng. Các thuật toán phổ biến như sha256 (Secure Hash Algorithm 256-bit), sha512, hay md5 (cái này thì 'lỗi thời' rồi, thầy sẽ giải thích sau).

const crypto = require('crypto');

// Dữ liệu 'đầu vào' của chúng ta
const originalData = 'Thầy Creyt đẹp trai và dạy code cực đỉnh!';
const anotherData = 'Thầy Creyt đẹp trai và dạy code cực đỉnh.!'; // Chỉ khác dấu chấm than

// --- Ví dụ 1: Hashing với SHA-256 ---
console.log('--- Hashing với SHA-256 ---');
const hashSha256 = crypto.createHash('sha256');
hashSha256.update(originalData); // 'Đổ' dữ liệu vào máy xay
const digestSha256 = hashSha256.digest('hex'); // Lấy 'ly sinh tố' ra, định dạng hex
console.log('Dữ liệu gốc:', originalData);
console.log('Hash SHA-256:', digestSha256);
// Output: 47b1f3c5a6d7e8f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4 (ví dụ)

// Thay đổi một chút xíu, xem hash có khác không?
const hashSha256_2 = crypto.createHash('sha256');
hashSha256_2.update(anotherData);
const digestSha256_2 = hashSha256_2.digest('hex');
console.log('Dữ liệu thay đổi nhỏ:', anotherData);
console.log('Hash SHA-256 (thay đổi):', digestSha256_2);
// Output: Rất khác biệt so với cái trên! Đây chính là tính "Avalanche effect"

// --- Ví dụ 2: Hashing với MD5 (chỉ để minh họa, không khuyến khích dùng cho bảo mật) ---
console.log('\n--- Hashing với MD5 (KHÔNG DÙNG CHO BẢO MẬT!) ---');
const hashMd5 = crypto.createHash('md5');
hashMd5.update('Mật khẩu của tôi là 123456');
const digestMd5 = hashMd5.digest('hex');
console.log('Dữ liệu gốc:', 'Mật khẩu của tôi là 123456');
console.log('Hash MD5:', digestMd5);
// Output: e10adc3949ba59abbe56e057f20f883e (ví dụ)

// --- Ví dụ 3: Hashing một file (thực tế hơn) ---
// Giả sử bạn có một file 'my_document.txt'
/*
const fs = require('fs');

const filePath = './my_document.txt'; // Đảm bảo có file này trong cùng thư mục
const hashFile = crypto.createHash('sha256');
const input = fs.createReadStream(filePath);

input.on('data', (chunk) => {
    hashFile.update(chunk);
});

input.on('end', () => {
    const fileDigest = hashFile.digest('hex');
    console.log(`\nHash SHA-256 của file ${filePath}:`, fileDigest);
});

input.on('error', (err) => {
    console.error('Lỗi khi đọc file:', err);
});
*/
// Để chạy ví dụ file, bạn cần tạo một file `my_document.txt` với nội dung bất kỳ.
// Ví dụ: echo "Đây là nội dung file test." > my_document.txt

Giải thích code:

  • require('crypto'): Gọi 'thủ thư' mang cuốn sách 'Mật mã học' ra cho chúng ta.
  • crypto.createHash('sha256'): Khởi tạo cái máy xay sinh tố, và nói rõ là 'xay theo công thức SHA-256 nha'.
  • hashSha256.update(originalData): Đổ dữ liệu vào máy xay. Mấy đứa có thể đổ nhiều lần, nó sẽ nối lại.
  • hashSha256.digest('hex'): Bấm nút 'xay' và lấy thành phẩm ra. hex là định dạng phổ biến, tức là chuỗi ký tự thập lục phân.
Illustration

3. Mẹo (Best Practices) để không 'Toang' khi dùng Hashing

Anh Creyt đã 'sống sót' qua nhiều dự án 'khó nhằn', nên anh có mấy lời khuyên 'vàng' cho mấy đứa đây:

Gợi Ý Đọc Tiếp
path.basename(): Tên file đâu, chỉ điểm ngay!

1 Lượt xem

  • MD5 là 'đồ cổ', tránh xa cho bảo mật! Thầy đã minh họa MD5 ở trên nhưng hãy nhớ: MD5 đã bị 'bẻ khóa' từ lâu rồi. Đừng bao giờ dùng nó để lưu trữ mật khẩu hay dữ liệu nhạy cảm. Nó giống như dùng chìa khóa vạn năng cho két sắt vậy, ai cũng mở được.
  • Luôn dùng thuật toán mạnh: Hiện tại, hãy ưu tiên sha256 hoặc sha512. Chúng vẫn được coi là an toàn cho hầu hết các trường hợp.
  • Hashing mật khẩu? createHash chưa đủ! Đây là lỗi 'kinh điển' của mấy đứa mới vào nghề. Mặc dù hashing là bước đầu, nhưng chỉ dùng createHash() để hash mật khẩu trực tiếp là cực kỳ nguy hiểm. Kẻ xấu có thể dùng 'rainbow tables' (bảng cầu vồng) để tìm ra mật khẩu gốc từ hash của mấy đứa.
    • Giải pháp? Phải dùng thêm salt (muối) và các hàm băm mật khẩu chuyên dụng như bcrypt hoặc scrypt. Salt là một chuỗi ngẫu nhiên được thêm vào mật khẩu trước khi hash, làm cho mỗi mật khẩu (dù giống nhau) cũng có hash khác nhau. Bcrypt/scrypt còn 'làm chậm' quá trình hashing một cách có chủ đích, khiến việc tấn công brute-force trở nên tốn kém hơn rất nhiều. Coi như 'thêm chướng ngại vật' cho kẻ gian vậy.
  • Encoding quan trọng: Luôn chỉ rõ encoding khi update() dữ liệu, ví dụ hash.update(data, 'utf8'). Nếu không, Node.js sẽ dùng buffer mặc định, có thể gây ra kết quả không mong muốn trên các hệ thống khác nhau.

4. Ứng Dụng Thực Tế: Hashing ở đâu trong thế giới ảo?

Hashing không phải là thứ 'trên trời' đâu, nó ở khắp mọi nơi mà mấy đứa đang dùng hàng ngày đấy:

  • Khi mấy đứa đăng nhập vào Facebook, Instagram, TikTok: Mật khẩu của mấy đứa không được lưu trữ 'nguyên xi' trong database của họ đâu. Thay vào đó, họ lưu trữ hash của mật khẩu (cùng với salt và các kỹ thuật bảo mật khác). Khi mấy đứa nhập mật khẩu, hệ thống sẽ hash nó và so sánh với hash đã lưu. Nếu khớp, 'Chào mừng bạn trở lại!'.
  • Download phần mềm, game từ mạng: Đôi khi mấy đứa thấy có một chuỗi ký tự dài ngoằng bên cạnh link download, đó chính là checksum (tổng kiểm tra) hay hash của file đó. Sau khi download xong, mấy đứa có thể tự tính hash của file vừa tải về và so sánh với checksum mà nhà cung cấp đưa ra. Nếu trùng khớp, an tâm file không bị 'đổi ruột' hay virus trên đường truyền.
  • Blockchain và Tiền điện tử (Bitcoin, Ethereum): Đây là 'sân chơi' lớn nhất của hashing. Mỗi 'block' trong blockchain chứa hash của block trước đó. Điều này tạo thành một chuỗi không thể thay đổi. Nếu ai đó cố gắng sửa đổi một giao dịch trong một block cũ, hash của block đó sẽ thay đổi, làm 'toang' toàn bộ chuỗi tiếp theo, và cả mạng lưới sẽ phát hiện ra ngay lập tức. Đó là cách blockchain đảm bảo tính toàn vẹn và bất biến.
  • Chữ ký số (Digital Signatures): Hashing được dùng để tạo ra một 'bản tóm tắt' của tài liệu. Sau đó, bản tóm tắt này được mã hóa bằng khóa riêng của người gửi, tạo thành chữ ký số. Người nhận dùng khóa công khai của người gửi để giải mã chữ ký và so sánh hash đó với hash của tài liệu mà họ tự tính. Nếu khớp, chứng tỏ tài liệu không bị sửa đổi và đúng là do người gửi đó gửi.

5. Thử Nghiệm và Nên Dùng Cho Case Nào

Thử nghiệm đã từng: Thầy Creyt đã từng 'ngây thơ' dùng MD5 để hash mật khẩu cho một dự án nhỏ hồi sinh viên. Hậu quả là gì? Vài năm sau, có một vụ rò rỉ dữ liệu, và mật khẩu của người dùng bị 'phơi bày' vì MD5 quá yếu. Đó là bài học xương máu về việc không bao giờ 'lười' trong bảo mật. Từ đó, thầy luôn 'ám ảnh' với việc dùng đúng công cụ cho đúng việc.

Nên dùng crypto.createHash() cho các trường hợp sau:

  • Tạo checksum cho file/dữ liệu: Để kiểm tra tính toàn vẹn, ví dụ như kiểm tra xem một file ảnh đã tải về có bị hỏng không, hoặc một gói dữ liệu gửi qua mạng có bị mất mát bit nào không.
  • Tạo ID duy nhất từ dữ liệu: Nếu mấy đứa cần một ID duy nhất dựa trên nội dung của một chuỗi hoặc đối tượng (ví dụ: cache key), hashing là một lựa chọn tốt.
  • Là một phần của hệ thống bảo mật lớn hơn: Như đã nói, nó là 'viên gạch' cơ bản để xây dựng các hệ thống phức tạp hơn như lưu trữ mật khẩu an toàn (kết hợp với salt và KDFs), hoặc trong các thuật toán chữ ký số.
  • Xác minh tính toàn vẹn trong Blockchain: Đối với những dự án liên quan đến công nghệ sổ cái phân tán, hashing là cốt lõi.

KHÔNG NÊN dùng crypto.createHash() cho:

  • Mã hóa dữ liệu (Encryption): Hashing là một chiều, không thể giải mã. Nếu mấy đứa muốn mã hóa để sau này còn giải mã, hãy tìm đến các thuật toán mã hóa đối xứng (AES) hoặc bất đối xứng (RSA).
  • Lưu trữ mật khẩu trực tiếp: Nhắc lại lần nữa, createHash() alone không đủ an toàn. Dùng bcrypt hoặc scrypt!
  • Tạo số ngẫu nhiên an toàn (Cryptographically Secure Random Numbers): Mặc dù module crypto có các hàm cho việc này (crypto.randomBytes), createHash() không phải là công cụ để làm điều đó.

Tóm lại, crypto.createHash() là một công cụ mạnh mẽ và cực kỳ quan trọng trong hộp đồ nghề của bất kỳ dev nào. Hiểu rõ nó là gì, dùng khi nào và dùng như thế nào cho đúng sẽ giúp mấy đứa 'nâng tầm' code của mình lên một đẳng cấp mới, và quan trọng hơn là không 'gây họa' cho người dùng của mình. Nào, giờ thì tự tin mà 'xay' dữ liệu đi nhé!

Thuộc Series: Nodejs

Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!

#tech #cyberpunk #laravel
Chỉnh sửa bài viết

Bình luận (0)

Vui lòng Đăng Nhập để Bình luận

Hỗ trợ Markdown cơ bản
Nguyễn Văn A
1 ngày trước

Tính năng này đỉnh quá ad ơi, chờ mãi mới thấy một blog Tiếng Việt có UI/UX xịn như vầy!