Argon2 là gì: thuật toán băm mật khẩu chống GPU và ASIC

Argon2 là thuật toán băm mật khẩu được chọn làm chiến thắng cuộc thi Password Hashing Competition (PHC) vào ngày 20/7/2015, sau khi 24 mô hình tranh tấn bị loại dần còn 9 finalist rồi mới chọn ra một người thắng duy nhất. Nếu bạn đang lưu mật khẩu người dùng, thuật toán bạn nên dùng chính là Argon2, mặc định là biến thể Argon2id. Bài viết này giải thích cơ chế bên trong, các tham số cấu hình và cách đo đạc để chọn thông số an toàn.

Vì sao Argon2 khác bcrypt và PBKDF2

Điểm yếu cốt lõi của thuật toán băm mật khẩu cũ là chúng gần như chỉ tiêu tốn CPU. Kẻ tấn công có ASIC hoặc GPU chuyên dụng thì băm hàng triệu mật khẩu mỗi giây với chi phí điện rất thấp. PBKDF2 không có khái niệm tốn bộ nhớ nên rất dễ bị tăng tốc; bcrypt tốn khoảng 4 KB bộ nhớ cố định, tốt hơn PBKDF2 nhưng vẫn không đủ khó với thiết bị hiện đại.

Argon2 là thuật toán memory-hard, buộc kẻ tấn công phải dành cả bộ nhớ cho mỗi lần băm thay vì chỉ tiêu tốn số đơn vị xử lý. Theo tài liệu đặc tả chính thức, Argon2 lấp đầy 1 GB RAM trong chưa đầy một giây, nhanh hơn cả băng thông bộ nhớ hiện đại, khiến GPU và ASIC không thể mở rộng tuyến tính như các hàm băm chỉ dùng CPU. Bạn có thể tải bản đặc tả tại argon2-specs.pdf và lịch sử cuộc thi tại trang Password Hashing Competition.

Sơ đồ quy trình đăng ký: người dùng nhập mật khẩu qua kênh an toàn, máy chủ chạy thuật toán băm và chỉ lưu giá trị băm vào cơ sở dữ liệu

Sơ đồ trên mô tả luồng lưu trữ an toàn: phía người dùng gửi mật khẩu qua kênh được mã hóa, phía máy chủ chỉ giữ lại giá trị băm. Ngay cả khi kẻ tấn công lấy được toàn bộ cơ sở dữ liệu gồm giá trị băm và cả muối (salt), họ vẫn không có mật khẩu gốc để dùng lại cho các hệ thống khác.

Ba biến thể Argon2d, Argon2i và Argon2id

Argon2 có ba chế độ truy cập bộ nhớ khác nhau, ứng dụng cho ba tình huống khác nhau:

  • Argon2d: truy cập bộ nhớ phụ thuộc vào mật khẩu, sinh dữ liệu ngẫu nhiên tốc độ nhất nhưng dễ bị tấn công kênh bên (side-channel) vì kiểu truy cập bộ nhớ lộ theo dữ liệu.
  • Argon2i: truy cập bộ nhớ độc lập với mật khẩu và dữ liệu đầu vào, an toàn hơn trước side-channel nhưng chậm hơn vì phải quét bộ nhớ nhiều lượt hơn.
  • Argon2id: bản lai, nửa đầu lượt đầu dùng kiểu Argon2i rồi chuyển sang kiểu Argon2d cho các lượt còn lại, vừa chống side-channel vừa giữ tốc độ của Argon2d.

Trường type trong định dạng chuỗi băm lấy giá trị 0 cho Argon2d, 1 cho Argon2i và 2 cho Argon2id. RFC 9106 khuyến nghị dùng Argon2id khi bạn không chắc chắn về môi trường thực thi hoặc khi có nguy cơ tấn công kênh bên. Đây cũng chính là lựa chọn mặc định trong các thư viện phổ biến như argon2-cli và thư viện @node-rs/argon2.

Ba tham số bạn phải chỉnh

Argon2 nhận ba tham số chi phí chính, cùng một cặp muối 128 bit và thẻ đầu ra 256 bit:

  • m (memory cost): khối bộ nhớ tính bằng KiB. Giá trị hợp lệ nằm trong khoảng từ 8 lần p đến 2 mũ 32 trừ 1 KiB. Đây là tham số quan trọng nhất vì nó quyết định chi phí bộ nhớ mà kẻ tấn công phải chịu.
  • t (time cost): số lượt lặp, nhân trực tiếp với thời gian băm. Giá trị lớn hơn nghĩa là chậm hơn và an toàn hơn.
  • p (parallelism): số luồng xử lý song song, giúp tận dụng nhiều lõi CPU.
Sơ đồ quá trình đăng nhập: mật khẩu người dùng được băm rồi so khớp với giá trị băm đã lưu, khớp thì mới cho vào hệ thống

Ma trận khối bộ nhớ chính là nơi phát sinh độ khó: kẻ tấn công không thể tính trước khối cần dùng nếu không có toàn bộ bộ nhớ cùng lúc. Chính vì vậy, thông số bộ nhớ phải được cân nhắc dựa trên RAM thực tế của máy chủ, không chỉ dựa trên bộ vi xử lý.

Bảng thông số khuyến nghị chính thức

Hai nguồn tham chiếu đáng tin cậy đưa ra các bộ thông số khác nhau vì khác nhau về giả định tài nguyên. Bạn nên chọn theo tình huống của hệ thống:

Nguồn memory cost time cost parallelism Ghi chú
RFC 9106 lựa chọn 1 2^21 KiB (2 GiB) 1 4 Mặc định cho mọi môi trường
RFC 9106 lựa chọn 2 2^16 KiB (64 MiB) 3 4 Dành cho môi trường thiếu bộ nhớ
OWASP tối thiểu 19.456 KiB (19 MiB) 2 1 Phương án tiết kiệm
OWASP thay thế 47.104 KiB (46 MiB) 1 1 Ưu tiên hơn về bộ nhớ

Cả hai nguồn đều đặt mục tiêu thời gian băm một mật khẩu dưới một giây. Hướng dẫn đầy đủ nằm tại Password Storage Cheat Sheet của OWASP, phần định nghĩa ba tham số chi phí ở mục 3.1 của RFC 9106.

Đọc hiểu các con số hiệu năng

Trang README của dự án PHC công bố kết quả đo với bộ tham số 65.536 KiB, 3 lượt, 1 luồng cho thời gian băm khoảng 0,188 giây mỗi mật khẩu. Ở cấu hình rất nhỏ, một lượt băm với 1 MiB bộ nhớ và một luồng mất khoảng 0,004 giây, tức khoảng 250 mật khẩu mỗi giây trên cùng một luồng. Ngược lại, khi tăng lên 4.096 MiB bộ nhớ với hai luồng, mỗi lượt băm mất khoảng 13 giây. Chi phí bộ nhớ vì vậy chi phối mạnh hơn số lượt lặp, nên đừng ham tăng t mà bỏ qua m.

Chi tiết hiệu năng trong đặc tả cho thấy Argon2d đạt 1,3 chu kỳ mỗi byte ở một luồng và giảm xuống 0,6 chu kỳ mỗi byte ở bốn luồng, tương ứng băng thông 3,8 GB/s lên 5,4 GB/s. Bạn có thể đối chiếu bảng số liệu gốc trong README dự án phc-winner-argon2.

So sánh nhanh với bcrypt và PBKDF2

OWASP khuyến nghị bcrypt với work factor tối thiểu 10 nhưng lưu ý bcrypt chỉ dùng được 72 byte đầu tiên của mật khẩu, còn PBKDF2-HMAC-SHA256 cần tối thiểu 600.000 lượt, PBKDF2-HMAC-SHA512 tối thiểu 220.000 lượt, và bản SHA-1 cũ cần 1.400.000 lượt. Chi tiết về giới hạn của bcrypt được ghi nhận tại trang bcrypt trên Wikipedia.

  • Argon2id: tốn bộ nhớ theo cấu hình, chống được cả GPU lẫn ASIC, thời gian băm điều chỉnh được.
  • bcrypt: tốn khoảng 4 KB bộ nhớ, không tăng theo work factor, cắt mật khẩu ở 72 byte.
  • PBKDF2: không memory-hard, dễ bị tốc độ hóa trên phần cứng chuyên dụng.

Điểm quan trọng khi chuyển đổi hệ thống cũ là ghi tham số vào chuỗi băm đã lưu, dạng $argon2id$v=19$m=65536,t=3,p=4$salt$hash. Nhờ vậy mỗi mật khẩu mang thông số riêng, bạn tăng cấu hình cho mật khẩu mới vẫn xác thực được mật khẩu cũ. Khi đăng nhập thành công, hãy băm lại bằng thông số mới để người dùng tự chuyển dần.

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

GIMP là gì: trình chỉnh sửa ảnh mã nguồn mở miễn phí đa nền tảng

GIMP là gì: trình chỉnh sửa ảnh mã nguồn mở miễn phí đa nền tảng GIMP là viết tắt của GNU Image Manipulation Program, một trình chỉnh sửa ảnh mã…

Xem thêm

tcpdump là gì: công cụ bắt và đọc gói tin mạng từ dòng lệnh

tcpdump là công cụ dòng lệnh phổ biến nhất thế giới dùng để bắt và phân tích gói tin mạng. Nó dùng thư viện libpcap để chuyển dữ liệu thô…

Xem thêm

VLC media player là gì: trình phát đa năng cho mọi định dạng

VLC media player là trình phát đa năng mã nguồn mở do dự án VideoLAN phát triển, chạy được trên máy tính lẫn điện thoại. Nhờ đọc được gần như…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất