Băm mật khẩu đúng cách

1/ Sử dụng scrypt, bcrypt, PBKDF2 hoặc argon2. Thuật toán nào trong số này cũng được, cứ chọn một cái mà dùng, thay thế cho MD5, SHA2, v.v.

2/ Băm _mỗi_ mật khẩu với một "muối" (salt) ngẫu nhiên dài 64 bit. Muối này không cần phải giữ bí mật, lưu chung với chỗ lưu mật khẩu cũng được.

3/ (Nâng cao) Băm _tất cả_ mật khẩu với một "tiêu" (pepper) ngẫu nhiên dài 128 bit. Tiêu này cần được giữ bí mật, lưu ở một máy chủ khác với chỗ lưu mật khẩu.

Tại sao phải làm những bước này? Tại sao thêm muối thôi không đủ? Tại sao cần phải có cả tiêu?

Các câu hỏi này tôi để dành cho các bạn sinh viên như là bài tập về nhà. Các bạn có thể trả lời vào phần comment bên dưới hoặc là email cho tôi ở thaidn@gmail.com.

Khoe cho các bạn sinh viên có cảm hứng trả lời câu hỏi: tôi thiết kế thuật toán băm mật khẩu đang được Google sử dụng để bảo vệ mật khẩu của tất cả người dùng.

Comments

Unknown said…
This comment has been removed by the author.
Quân said…
Ngoài điều (1) và (2) thì làm sao chứng minh được cách thứ (3) là cách băm đúng. Chưa hẳn nó được sử dụng tại Google thì mặc định nó sẽ đúng.
Thai Duong said…
Thì bạn có thể chỉ ra nó sai ở đâu mà?

Tôi cũng không có nói là nó được sử dụng tại Google và cũng không có nói là nếu sử dụng tại Google thì nó đúng.
Quân said…
Nhưng tiêu đề bài viết là 'Băm mật khẩu đúng cách' nên em nghĩ (chắc/có thể đã có chứng minh ở đâu đó). Em chỉ hỏi về thực tế đã có chứng minh chứa, không hề có ý đả kích hay gì khác.
Thai Duong said…
Àh tôi nghĩ là đúng nhưng mà tôi cũng rất muốn biết những ý kiến khác. Không sao đâu, tôi không có thấy phiền câu hỏi của bạn.
n0c3rt said…
Mình nghĩ vầy ko biết phải ko:
1. Băm - để ngăn lộ plaintext password, tuy nhiên có thể dò tìm hash dựa theo từ điển online hoặc tự xây dựng offline sẵn có
2. Muối - Ngăn dò tìm theo các từ điển online (đa số là băm thuần). Tuy nhiên nếu attacker cố gắng để tìm ra password của 1 account cụ thể thì có thể xây dựng từ điển dựa trên muối sẵn có - hơi mất thời gian hơn
3. Tiêu - thêm tiêu và giữ tiêu bí mật, thì ngay cả khi có muối, attacker cũng ko thể xây dựng từ điển chính xác để dò tìm
Unknown said…
Băm _mỗi_ mật khẩu với một "muối" (salt) ngẫu nhiên dài 64 bit:
- Muối phải độc nhất cho mỗi csdl, nhằm ngăn chặn nỗ lực tin tặc thịt được vào toàn bộ các chuỗi băm mật khẩu chỉ trong một lượt dò.
- Muối để ngăn chặn phương thức tấn công dùng bảng tổng hợp các chuỗi băm để tìm mật khẩu, có tên là rain gì đó em quên rồi...khi tấn công vét cạn, tin tặc không thể tạo ra tất cả các khả năng trong một lần, mà sẽ phải vét cạn từng mật khẩu kèm muối, kéo dài thời gian hơn.
Băm _tất cả_ mật khẩu với một "tiêu" (pepper) ngẫu nhiên dài 128 bit. Tiêu này cần được giữ bí mật, lưu ở một máy chủ khác với chỗ lưu mật khẩu.:
- Cần giữ bí mật thằng Tiêu này vì nếu Tiêu này vào tay tin tặc thì CSDL mình đúng nghĩa là tiêu thật :D
X said…
Em chào anh. Em không phải là SV, cũng ko phải là dân bảo mật, em là DEV 3 năm kinh nghiệm nhưng tự thấy vẫn là fresher :D Tuy nhiên, em xin phép trả lời 1 cách nghiêm túc theo ý hiểu của em.

1. Với MD5: cùng input thì output luôn giống nhau
Bcrypt thì trong nó đã có sẵn salt => mỗi lần mã hóa 1 input sẽ có output khác nhau.
=> bcrypt > md5

2. Việc thêm muối sẽ giúp hacker khó tìm ra thuật toán mã khóa, tránh brute force theo kiểu tạo 1 CSDL mapping password với hash chẳng hạn. Vì việc nhét muối theo thứ tự nào cũng gây khó dễ nhất định rồi.
Em xin bỏ qua về phần độ dài 64 bit vì em ko biết.

3. Sẽ là lý tưởng nếu muối là private, nhưng như thế sẽ phải lưu trữ list muối đó trong 1 CSDL mới. Mà theo lý thuyết CSDL đó vẫn có thể bị hack :D
=> nên focus lưu tiêu duy nhất và cố gắng bảo vệ 1 mình nó thôi :D

// Gõ đến đây em thấy không tự tin đúng và em hi vọng 1 ngày nào đó a sẽ viết một post cụ thể hơn về chủ đề này ạ.

// Hiện nay đa phần Dev xung quanh em và em đều chỉ dùng sẵn cơ chế Auth mà các framework support nên ko đi sâu vào việc tổ chức hay thiết kế thuật toán mã hóa :(
quangntenemy said…
Theo tôi băm mật khẩu cũng giống băm thịt khi làm món thịt năm viên, nó tuỳ khẩu vị mỗi người.
Bản thân tôi thì thường cho thêm gia vị + hành. Muối hay tiêu cho thêm 1 ít cũng được nhưng chỉ là phụ thôi.
Nếu chỉ muối thì mặn , thêm tiêu nữa cay lại ngon . ^^
Ned said…
Muối là để khiến việc giải mã tất cả mật khẩu của khách hàng trở nên khó kh n.
Tiêu là để khiến việc giải mã mật khẩu của một khách hàng nhất định trở nên khó kh ăn (ví dụ khách hàng đó có thể là một nhân vật đặc biệt nào đó).
Unknown said…
Vậy trong trường hợp xấu nhất cryto algo bị decrypted ngược lại theo cách 51-51 trong block chain thì sao ?
Unknown said…
Ý kiến cá nhân về việc băm mật khẩu:

1. Sử dụng các thuật toán như md5, sha1, sha2 đơn thuần không đủ để đảm bảo mật khẩu không bị giải mã với tấn công brute force bởi với sức mạnh của GPU và công cụ như hashcat, người ta có thể thử lên tới hàng tỷ mật khẩu mỗi giây. Các thuật toán như bcrypt,... làm cho việc brute force trở nên khó khăn vì cùng với 1 sức mạnh GPU để thử hàng tỷ mật khẩu cho md5, aes, người ta chỉ có thể thử được vài chục ngàn mật khẩu mỗi giây với brypt.

2. Giả sử sử dụng md5, hay sha1. Việc băm mật khẩu với 1 salt sẽ tránh cho việc kẻ tấn công sử dụng những cơ sở dữ liệu về mã hash như hashkiller để tìm ra mật khẩu một cách nhanh chóng với việc search.

3. Việc băm thêm mật khẩu với 1 tiêu thì có lẽ là chiến lược: "không để tất cả trứng trong cùng một giỏ". Ví dụ như 1 ứng dụng web có lỗ hổng sql injection, kẻ tấn công lấy được salt, password hash cũng không thể thực hiện tấn công brute force giải mã mật khẩu được vì thiếu mất pepper.
Anh Dung Bui said…
Hi anh

Em có thắc mắc về phần tích hợp của ngân lượng (https://www.nganluong.vn//data/developer_home/NL_checkout_v2.7_vn.doc)
Ở đây mỗi request gửi lên server của ngân lượng phải thêm một checksum, họ tính checksum bằng cách:
MD5(parameters + mật khẩu giao dịch). Theo em hiểu là để kiểm tra data integrity và authentication.

Như vậy rõ ràng họ phải lưu mật khẩu giao dịch dạng plaintext thì mới kiểm tra checksum được. Nếu coi mật khẩu giao dịch là secret key thì đúng là có thể lưu plaintext (hoặc mã hoá bởi một key dùng chung).

Theo anh cách làm trên có vấn đề gì và best practices là gì ạ?

Thanks anh.
Unknown said…
Có 3 vấn đề với mật khẩu đó là gồm : việc băm - việc lưu trữ sau băm - và việc kiểm tra.
- Giải thuật băm làm cho mật khẩu không thể giải ngược lại. Lý thuyết là vậy
- Nhưng vì giải thuật băm là công khai, nên có thể tra ngược mật khẩu từ các chuỗi băm đã được ghi nhận từ trước. Nên các mật khẩu yếu sẽ bị hạ đầu tiên, số lượng mật khẩu yếu rất nhiều, thời gian tra cứu rất nhanh, sẽ có rất nhiều người dùng với mật khẩu yếu bị phát hiện. Muối được thêm vào để mọi mât khẩu yếu đều trở thành mật khẩu mạnh. Khi đó mọi giá trị băm là không thể giải mã tra ngược
- Có muối ko lo tra ngược từ mật khẩu sinh ra từ hàm băm - nhưng lúc giải mã mà ko có muối - là cũng chịu ko xác thực người dùng được. Vì thế muối phải lưu lại, mà muốn lưu cho nhanh tra cứu thì phải đặt cùng chỗ với dữ liệu xuất ra từ hàm băm. Vậy nên lại có việc để làm, đó là với 1 user chỉ định cụ thể, hacker xâm nhập dữ liệu rồi cứ đem tập từ điển + muối đã biết = xuất ra dữ liệu băm và so chiếu với hiện tại để bẻ các mật khẩu yếu. Hacker bị hạn chế tốc độ, chứ ko hạn chế độ khó khi bẻ khoá mật khẩu.
- Thêm tiêu lưu ở chỗ khác, bản chất cũng là muối nâng cấp, nhưng việc chia mật khẩu ra làm 2 giúp cho hacker khi xâm nhập được 1 hệ thống, không đủ dữ liệu để đoán mật khẩu nhập từ người dùng. Hacker bị hạn chế về đầy đủ dữ liệu, có vẻ là không thể dò ngược mật khẩu, nhưng nếu đã hạ được hệ thống để lấy muối, việc đập bình lấy tiêu cũng có tỷ lệ tin tưởng.





Unknown said…
em chào anh, em đang làm về mã hóa cho một ví điện tử việt nam. A có tài liệu về quy định mã hóa cho ví của google ko? có thể chia sẻ cho em không? Hoặc anh có thể viết bài về security cho ví diện tử được không?
em cảm ơn.
Unknown said…
Chào bạn Thái,

Lời đầu tiên cho mình gửi tới bạn lời chúc tốt lành nhất.
Mình đang gặp vấn đề với gmail và có nguy cơ bị mất luôn tài khoản vì tội quên mật khẩu, mình mất luôn cả email để khôi phục (recovery email), trong khi khi cài đặt mình có để cả số điện thoại để khôi phục khi quên mật khẩu (đồng thời cũng là số phone để xác minh 2 bước) nhưng khi thao tác khôi phục mật khẩu gmail không cho lựa chọn số điện thoại để khôi phục, chỉ ra lựa chọn khôi phục qua email.
mình đang rất là chán nản vì có phần suy sụp vì làm theo cả hướng dẫn khôi phục bằng cách câu hỏi ngày tháng năm sinh của account đó, nhưng mình không nhớ, có bao gồm cả một bước xác minh lấy code qua số điện thoại đã khai trước đó, và cho địa chỉ email khác để gmail gửi thông báo là họ có duyệt email đó là của mình hay không, nhưng đều không được, trong số 3 câu hỏi chỉ trả lời đúng số điện thoại và lấy code để trả lời câu hỏi tiếp theo. mình vẫn không khôi phục để hoạt động email gmail được.

mong bạn góp ý với bảo mật của google để khi mình không vào được recovery email mình vẫn có thể khôi phục qua recovery phone mà mình đã đăng ký.

Cảm ơn bạn đã đọc những dòng này rất nhiều. Và mong có phép màu mình sẽ khôi phục được mật khẩu và hoạt động email bình thường.
Thai Duong said…
hay quên: bạn có thể email cho tôi ở thaidn@gmail.com.
Quang Nguyễn said…
Không rõ mục đích của facebook thế nào nữa. Em đã thử một số tài khoản facebook cùng bạn bè mình thì phát hiện ra thế này. Giả sử mật khẩu facebook em là Vietnam2019 thì thêm bất kì 1 ký tự nào vào sau cùng hoặc đầu tiên vẫn login bình thường. Ví dụ xVietnam2019 hoặc Vietnam2019x vẫn login vào được. Mọi người ai có facebook thì test thử nhé
Unknown said…
Anh em có thể tìm hiểu kỹ hơn về thuật toán Argon2 tại: https://huongdandaotienao.com/argon2-la-gi/