Trình tạo & xác minh băm mật khẩu

Băm và xác minh mật khẩu bằng bcrypt, scrypt, Argon2id và PBKDF2 hoàn toàn trong trình duyệt — tạo chuỗi định dạng PHC, kiểm tra một mật khẩu ứng viên với một băm có sẵn, và xem các tham số ẩn bên trong. Không có gì được tải lên.
Chỉ dùng cho mật khẩu thử nghiệm. Mật khẩu người dùng thật không bao giờ nên dán vào bất kỳ trang web nào. Công cụ này chạy hoàn toàn trong trình duyệt — chuỗi không bao giờ rời tab của bạn — nhưng một vụ rò rỉ thật bắt đầu từ một lần dán.
chi phí bcrypt (2^cost vòng)
biến thể bcrypt biến thể chỉ đổi tiền tố; bản thân băm thì giống hệt nhau
scrypt N (chi phí CPU)
scrypt r / p r =   p = kích thước khối 128·r byte; bộ nhớ = 128·N·r byte (N=214, r=8 → 16 MiB)
Argon2id m (bộ nhớ)
Argon2id t / p t =   p = t = số lượt; p = song song (số làn)
PRF của PBKDF2
Số lần lặp PBKDF2  OWASP 2023: 600.000 cho HMAC-SHA-256 (1.300.000 cho SHA-1, 210.000 cho SHA-384/512)
Độ dài đầu ra (byte)  Đầu ra bcrypt cố định 23 byte (31 ký tự bcrypt-base64)
Thuật toánTham sốBộ nhớĐộ dài đầu raThời gian (trình duyệt này)
bcryptcost 124 KiB23 byte-
scryptN=214, r=8, p=116 MiB32 byte-
Argon2idm=19 MiB, t=2, p=119 MiB32 byte-
PBKDF2HMAC-SHA-256, 600.000 vòng~032 byte-
Bảng tham số nhanh (OWASP Password Storage Cheat Sheet, mức tối thiểu 2023)
Thuật toánTối thiểuGhi chú
Argon2idm = 19 MiB (19.456 KiB), t = 2, p = 1được ưu tiên; tốn bộ nhớ
scryptN = 214, r = 8, p = 1tốn bộ nhớ (16 MiB ở mức tối thiểu)
bcryptcost = 10chỉ có hệ số công việc; giới hạn mật khẩu 72 byte
PBKDF2-HMAC-SHA256600.000 vòng lặpchỉ khó theo vòng lặp — thân thiện với GPU, lựa chọn cuối cùng
Các mặc định của trang này đều ở mức hoặc trên mọi mức tối thiểu. Với production, hãy chọn Argon2id trước; scrypt hoặc bcrypt nếu không có; PBKDF2 chỉ vì lý do tuân thủ FIPS.
Tương thích PHP — password_hash($pw, PASSWORD_BCRYPT) sinh ra $2y$10$...: dán vào Xác minh cùng mật khẩu ứng viên và trang này trả lời đúng những gì password_verify() sẽ trả lời. Đầu ra PASSWORD_ARGON2ID ($argon2id$v=19$m=65536,t=4,p=1$...) cũng xác minh được. Chuỗi PHC từ passlib, django-argon2 và phần bọc crypto.scrypt cũng được phân tích.
Tự kiểm tra
Chạy lại engine của trang với các vector công khai: bộ kiểm thử crypt_blowfish cho bcrypt, chuỗi scrypt và Argon2id do node/OpenSSL tạo, các vector PBKDF2 từ RFC 6070 và bộ SHA-256 công khai, cùng các vòng tạo-rồi-xác-minh trong mọi thuật toán và kiểm thử âm (mật khẩu sai phải thất bại, chuỗi sai định dạng phải bị từ chối). Không có gì được gửi đi đâu cả.
Băm mật khẩu giải thích từ đầu
Tóm lại: hàm băm mật khẩu cố ý chậm (và tốt nhất là tốn bộ nhớ) để việc đánh cắp cơ sở dữ liệu không cho kẻ tấn công thử hàng tỷ phỏng đoán mỗi giây — ngược với mục tiêu của một hàm băm nhanh như SHA-256, vốn được thiết kế để nhanh.
Vì sao không chỉ băm SHA-256 mật khẩu?

SHA-256 trên GPU hiện đại chạy hàng tỷ phỏng đoán mỗi giây. Một mật khẩu 8 ký tự có dưới 1013 tổ hợp — hàng giờ GPU, vài phút trên một hệ thống lớn. Các hàm băm mật khẩu (KDF) chống lại điều này bằng tham số chi phí: bcrypt lặp lõi của nó 2cost lần, PBKDF2 lặp HMAC hàng trăm nghìn lần, scrypt và Argon2id còn đòi hỏi vài megabyte bộ nhớ cho mỗi phỏng đoán để GPU (nhanh nhưng ít bộ nhớ trên mỗi nhân) mất lợi thế. Salt — ngẫu nhiên, được lưu công khai bên trong chuỗi băm — ngăn bảng cầu vồng được tính sẵn và buộc mỗi phỏng đoán phải được tính lại từ đầu cho từng người dùng.

Bốn thuật toán trên trang này
Thuật toánNămĐộ khóĐịnh dạng chữ kýLưu ý
bcrypt1999CPU (2cost lần thiết lập khóa)$2b$12$ + salt 22 ký tự + băm 31 ký tựGiới hạn mật khẩu 72 byte (mọi thứ sau 72 bị bỏ qua lặng lẽ); byte NUL kết thúc mật khẩu trong triển khai C gốc
PBKDF22000 (RFC 2898/8018)CPU (số vòng lặp)$pbkdf2-sha256$i=600000$ + salt + băm (kiểu passlib)không có chi phí bộ nhớ — GPU và ASIC rất thích; chỉ số vòng lặp là tham số điều chỉnh được
scrypt2009 (RFC 7914)CPU + bộ nhớ (128·N·r byte)$scrypt$ln=14,r=8,p=1$ + salt + bămN phải là lũy thừa của hai; bộ nhớ tăng tuyến tính theo r
Argon2id2015 (người thắng PHC, RFC 9106)CPU + bộ nhớ (m KiB, t lượt)$argon2id$v=19$m=19456,t=2,p=1$ + salt + bămArgon2i (không phụ thuộc dữ liệu) so với Argon2d (phụ thuộc dữ liệu) so với Argon2id (lai) — luôn chọn id trừ khi bạn biết lý do không
Độ khó theo bộ nhớ so với độ khó theo tính toán

Một GPU có hàng ngàn nhân nhưng mỗi nhân chỉ truy cập được một lượng nhỏ bộ nhớ nhanh. Một KDF cần 19 MiB tập làm việc cho mỗi phỏng đoán giới hạn kẻ tấn công ở số phỏng đoán song song bằng số khối 19 MiB họ có — đó là lý do Argon2id ở 19 MiB trong thực tế có thể mạnh hơn bcrypt cost 15 dù tốn ít thời gian đồng hồ hơn trên laptop của bạn. PBKDF2 không có câu trả lời cho điều này: núm điều chỉnh duy nhất của nó là số lần lặp, và silicon mở rộng tuyến tính theo số đó.

Đọc chuỗi PHC

Định dạng modular-crypt / PHC tự mô tả: trong $argon2id$v=19$m=19456,t=2,p=1$ICEiIyQlJicoKSorLC0uLw$WTGpK4hf... các trường là thuật toán, phiên bản, tham số (m = bộ nhớ tính bằng KiB, t = số lượt, p = số làn), salt base64, băm base64. bcrypt có trước chuẩn và dùng dạng gọn riêng: biến thể $2b$, 12 là cost, rồi salt và băm trong bảng chữ base64 riêng của bcrypt (./A-Za-z0-9). Phần Xác minh của trang này chấp nhận tất cả các dạng này và hiển thị các trường đã phân tích — dán bất kỳ băm nào bạn tìm thấy và xem nó được tách thành gì.

Những lỗi thường gặp
  • Băm nhanh cho mật khẩu. Cột mật khẩu dùng MD5/SHA-1/SHA-256 bị GPU thông thường bẻ với hàng tỷ phỏng đoán mỗi giây. Dùng Trình tạo băm cho tệp và dữ liệu; dùng các thuật toán của trang này cho mật khẩu.
  • Dùng chung salt. Một salt cho mọi người dùng nghĩa là mật khẩu giống nhau có băm giống nhau và bảng cầu vồng quay lại. Mỗi băm ở đây nhận một salt 16 byte ngẫu nhiên mới.
  • Bỏ qua giới hạn 72 byte của bcrypt. "a"*100 và "a"*72 băm giống hệt nhau — phần đuôi bị bỏ. Trang này cảnh báo ở ô nhập khi mật khẩu vượt 72 byte. Argon2 không có giới hạn đó.
  • So sánh băm bằng == trong mã của bạn. Xác minh phải chạy trong thời gian không đổi; engine của trang làm điều đó bên trong (tính lại và so sánh các byte đã lưu), nhưng nếu bạn sao chép cách làm, hãy dùng phép so sánh thời gian không đổi.
  • Điều chỉnh tham số trên máy phát triển nhanh. Nhắm khoảng 250–500 ms băm trên phần cứng trung vị của người dùng production, không phải máy trạm của bạn. Nút Benchmark cho thấy trình duyệt này thực sự trải nghiệm ra sao.
  • Băm lại ở mỗi lần kiểm tra đăng nhập. Xác minh trước; chỉ băm lại (ví dụ để tăng chi phí) sau khi xác minh thành công, và lưu chuỗi mới. Hàm PHP password_needs_rehash() tồn tại đúng cho việc này.
Câu hỏi thường gặp

Nên chọn cái nào? Argon2id với ít nhất mức tối thiểu OWASP. Nếu runtime không có nó: scrypt, rồi bcrypt (cost sao cho băm mất ≥250 ms). PBKDF2 chỉ khi chứng nhận yêu cầu.

Vì sao salt ngẫu nhiên hiển thị trong chuỗi đầu ra? Salt không phải bí mật — nó được lưu công khai trong chuỗi PHC có chủ đích, nên xác minh chỉ cần chuỗi và mật khẩu ứng viên. Nhiệm vụ của nó là tính duy nhất, không phải bí mật.

Biến thể ($2a$ / $2b$ / $2y$) có quan trọng không? Với mật khẩu ASCII chúng cho cùng băm; $2a$ là bản gốc thập niên 1990, $2b$ sửa một lỗi sign-extension hiếm (2014), $2y$ là dấu hiệu của PHP rằng bản sửa có mặt. Xác minh chấp nhận cả ba.

Một băm nên mất bao lâu? Khoảng 250–500 ms mỗi lần đăng nhập trên phần cứng máy chủ. Dưới 100 ms thì bẻ ngoại tuyến rẻ; trên 1 s thì người dùng phàn nàn trước khi bảo mật tốt hơn.

Tôi có thể xác minh một băm tạo ở nơi khác không? Có — dán nó và cung cấp mật khẩu ứng viên. Các định dạng đã biết: password_hash của PHP (bcrypt $2y$ và Argon2id), Python passlib, bộ băm argon2 của Django, và định dạng chuỗi scrypt dùng bởi công cụ scrypt của Tarsnap.

Nút "benchmark" làm gì? Nó băm mật khẩu hiện tại một lần với mỗi thuật toán ở tham số mặc định của trang và báo thời gian đồng hồ trên trình duyệt này — để cảm nhận chênh lệch chi phí, không phải phép đo nghiêm ngặt.