Có an toàn hơn để băm mật khẩu nhiều lần?


43

Tôi đã đọc một vài lần rằng khi lưu trữ mật khẩu, rõ ràng là nên 'nhân đôi băm' các chuỗi (ví dụ: với md5 rồi sha1, cả hai đều có muối).

Tôi đoán câu hỏi đầu tiên là "điều này có thực sự đúng không?" Nếu không, xin vui lòng, bỏ qua phần còn lại của câu hỏi này :)

Lý do tôi hỏi là trên mặt của nó, tôi sẽ nói rằng điều này có ý nghĩa. Tuy nhiên, khi tôi nghĩ về nó, mỗi khi một hàm băm được thử lại (có thể có thêm thứ gì đó vào nó), tất cả những gì tôi có thể thấy là có sự giảm bớt giới hạn trên về 'tính duy nhất' cuối cùng ... có liên quan đến đầu vào ban đầu.

Để tôi nói cách khác: chúng ta có x số chuỗi, khi được băm, được giảm xuống y chuỗi có thể. Đó là để nói, có những va chạm trong tập đầu tiên. Bây giờ đến từ tập thứ hai đến tập thứ ba, không thể xảy ra điều tương tự (ví dụ: va chạm trong tập hợp tất cả các chuỗi 'y' có thể dẫn đến cùng một hàm băm trong tập thứ ba)?

Trong đầu tôi, tất cả những gì tôi thấy là một 'kênh' cho mỗi lệnh gọi hàm băm, 'kênh' một tập hợp khả năng vô hạn vào một tập hợp hữu hạn, v.v., nhưng rõ ràng mỗi cuộc gọi đều hoạt động trên tập hữu hạn trước nó, cho chúng ta đặt không lớn hơn đầu vào.

Có lẽ một ví dụ sẽ giải thích sự huyên thuyên của tôi? Lấy 'hash_feft_a' sẽ cho 'a' và 'b' băm '1', và sẽ cho 'c' và 'd' băm '2'. Sử dụng chức năng này để lưu trữ mật khẩu, ngay cả khi mật khẩu là 'a', tôi có thể sử dụng mật khẩu 'b'.

Lấy 'hash_feft_b' sẽ cho '1' và '2' hàm băm '3'. Nếu tôi sử dụng như một 'băm thứ cấp' sau 'hash_feft_a' thì ngay cả khi mật khẩu là 'a' tôi có thể sử dụng 'b', 'c' hoặc 'd'.

Trên hết, tôi nhận được rằng nên sử dụng muối đó, nhưng chúng không thực sự thay đổi thực tế rằng mỗi lần chúng ta ánh xạ các đầu vào 'x' thành đầu ra 'nhỏ hơn x'. Tôi không nghĩ.

Ai đó có thể vui lòng giải thích cho tôi những gì tôi đang thiếu ở đây?

Cảm ơn!

EDIT: vì những gì đáng giá, tôi không tự làm điều này, tôi sử dụng bcrypt. Và tôi không thực sự lo lắng về việc nó có hữu ích cho việc 'sử dụng chu kỳ' cho một 'hacker' hay không. Tôi thực sự chỉ đang tự hỏi liệu quá trình này có làm giảm "bảo mật" từ quan điểm va chạm băm hay không.


2
@ S.Lott: Tôi thực sự không thấy câu trả lời của câu hỏi thực tế như thế nào, mặc dù ... tất cả những gì nó nói là "đừng tự làm, hãy sử dụng thứ này" hoặc "thật tốt khi mất thời gian!". .. không có câu trả lời nào "nó thực sự an toàn hơn". Một lần nữa, trừ khi tôi thiếu một cái gì đó.
Narcissus

@MetalMikester: Vâng, đó là bài viết ngày hôm qua: thedailywtf.com/Articles/Bulletproof-Encryption.aspx
FrustratedWithFormsDesigner

Đây không phải là chủ đề cho Bảo mật CNTT, nhưng nó có vẻ như là một kết hợp tốt cho Mật mã học. Trong thực tế, nó trông cực kỳ giống với câu hỏi này .

Tôi biết một công ty muốn sử dụng không ướp muối MD5(password). Chúng tôi đã nói rằng nó không an toàn, vì vậy họ đã đề xuất sử dụng MD5(MD5(password))thay thế ...
cấu hình

Câu trả lời được chấp nhận không phải là câu trả lời đúng!
markus

Câu trả lời:


27

Điều này phù hợp hơn trên security.stackexchange nhưng ...

Vấn đề với

hash1(hash2(hash3(...hashn(pass+salt)+salt)+salt)...)+salt)

là nó chỉ mạnh như hàm băm yếu nhất trong chuỗi. Ví dụ: nếu hàm băm (hàm băm trong cùng) tạo ra xung đột, toàn bộ chuỗi băm sẽ tạo ra xung đột ( không phân biệt các giá trị băm khác trong chuỗi ).

Một chuỗi mạnh mẽ hơn sẽ là

hash1(hash2(hash3(...hashn(pass + salt) + pass + salt) + pass + salt)...) + pass + salt)

Ở đây chúng tôi tránh được sự cố va chạm sớm và về cơ bản chúng tôi tạo ra một loại muối phụ thuộc vào mật khẩu cho hàm băm cuối cùng.

Và nếu một bước trong chuỗi va chạm thì điều đó không thành vấn đề bởi vì trong bước tiếp theo, mật khẩu được sử dụng lại và sẽ cho kết quả khác nhau cho các mật khẩu khác nhau.


Vì vậy, ngay bây giờ tôi thấy rằng việc thêm "mật khẩu + muối" làm muối vào vòng băm tiếp theo có thể sẽ làm tăng lượng 'thứ' có thể đi vào kênh, bây giờ tôi chỉ cần hiểu 'bao nhiêu'. Cảm ơn.
Narcissus

Trên thực tế tôi nghĩ rằng tôi đã có được nó ngay bây giờ: bằng cách buộc mật khẩu vào từng lớp băm, liệu nó có thực sự làm giảm số lượng va chạm có thể xảy ra hay không bằng cách yêu cầu 'mật khẩu va chạm' và mật khẩu thực sự có băm phù hợp qua mỗi 'cuộc gọi' , đúng? Tôi nghĩ rằng tôi đã thiếu phần 'đặt mật khẩu ở mỗi lớp'! Cảm ơn một lần nữa.
Narcissus

@Narcissus không có thăm dò và điều đó cũng có phần thưởng cho phép băm bên trong yếu hơn (miễn là băm bên ngoài / cuối cùng mạnh) vì các băm bên trong chỉ tạo ra muối cho lần vượt qua tiếp theo
ratchet freak

hum, tôi nghĩ rằng vấn đề lớn hơn một chút (và sâu hơn). Với các cuộc tấn công cầu vồng, bạn chỉ có thể tạo các bảng xem xét tất cả các giá trị băm của mình và vấn đề vẫn còn.
woliveirajr

4
@Narcissus: trong một câu trả lời rất ngắn: Có, nó không an toàn hơn . Vâng, có lẽ nó thậm chí còn kém an toàn hơn .
woliveirajr

54

Sử dụng các thuật toán băm khác nhau là một ý tưởng tồi - nó sẽ làm giảm entropy thay vì tăng nó.

Tuy nhiên, giả sử bạn có thuật toán băm mạnh về mật mã và muối tốt, việc áp dụng cùng hàm băm nhiều lần sẽ khiến quá trình băm tốn kém hơn về mặt tính toán. Lợi ích của việc này là khi các phương pháp bẻ khóa mật khẩu khác không thành công (đoán, tấn công từ điển, bảng cầu vồng, v.v.) và kẻ tấn công buộc phải sử dụng các kỹ thuật vũ phu, chúng sẽ mất nhiều thời gian hơn để thử từng mật khẩu, đơn giản vì họ phải áp dụng cùng hàm băm thường xuyên hơn. Vì vậy, nếu một vòng băm sẽ cần một tháng vũ phu, áp dụng nó mười hai lần sẽ tăng thời gian ước tính lên một năm.

Các thuật toán băm gần đây như bcrypt xây dựng trên ý tưởng này; chúng chứa một tham số để kiểm soát độ phức tạp tính toán của hàm băm, để bạn có thể mở rộng quy mô khi tốc độ phần cứng tăng lên: khi phần cứng trở nên nhanh hơn theo hệ số hai, bạn tăng độ phức tạp để bù lại, do đó thời gian cần thiết để bắt buộc băm vẫn không đổi.


2
Đây là câu trả lời chính xác!
markus

@markus: theo như cuộc thảo luận mà tôi đã đọc, điều này chỉ đúng vì bổ sung "và một loại muối tốt" được giải quyết bằng câu trả lời được chấp nhận, phải không? Tại sao điều này là đúng và câu trả lời được chấp nhận không?
Narcissus

Đây là câu trả lời đúng vì lý do duy nhất để áp dụng cùng hàm băm nhiều lần (được tham số hóa) là bạn có thể sử dụng phép lặp này để điều chỉnh cho phần cứng nhanh hơn. Nếu không, không có lợi ích từ băm nhiều lần.
markus

@Narcissus Chìa khóa ở đây là entropy. Có sự khác biệt giữa băm nhiều lần bằng cùng một phương thức so với băm nhiều lần bằng các phương pháp khác nhau.
sakisk

3

Đừng cố gắng viết sơ đồ băm mật khẩu của riêng bạn trừ khi bạn sẵn sàng tham gia một khóa học về mật mã và / hoặc kỹ thuật bảo mật.

Bạn nên sử dụng một triển khai băm mật khẩu được thiết lập tốt, lần lượt sẽ sử dụng chức năng phái sinh chính ( KDF ) như PBKDF2, bcrypt, scrypt hoặc Argon2 mới hơn.

Các KDF tốt bao gồm một trình xử lý công việc, thường là một số lần lặp lại, để tăng chi phí cho các cuộc tấn công ngoại tuyến. Người ta có thể nói rằng các KDF này băm mật khẩu nhiều lần, sử dụng cùng một thuật toán mỗi lần. Không có điểm nào trong việc sử dụng thuật toán tiêu hóa nhiều thông điệp, như được chỉ ra bởi những người khác.


1
liên kết https://crackstation.net/hashing-security.htmlm bị chặn bởi tường lửa
gnat

1
@gnat Vì một số lý do, tôi đã bỏ lỡ nhận xét của bạn về URL bị chặn. Tôi đã thay thế nó bằng một liên kết đến wikipedia.
Erwan Legrand

2

Nói chung, bạn không cần sử dụng nhiều hơn một thuật toán băm.

Những gì bạn cần làm là:

Sử dụng muối: muối không được sử dụng chỉ để làm cho mật khẩu của bạn an toàn hơn , nó được sử dụng để tấn công bảng cầu vồng. Bằng cách đó, ai đó sẽ có một công việc khó khăn hơn khi cố gắng tính toán trước hàm băm cho mật khẩu bạn lưu trữ trong hệ thống của bạn.

Sử dụng nhiều tương tác: thay vì chỉ thực hiện SHA (mật khẩu + muối), hãy thực hiện SHA (SHA (SHA (SHA (SHA (... SHA (mật khẩu + muối)))))). Hoặc, để đại diện theo cách khác:

hash = sha(password + salt)
for i=1 , i=5000, i++ {
    hash = sha(hash + salt);
}

Và, cuối cùng, chọn một chức năng băm tốt. SHA, MD5, v.v., không tốt vì chúng quá nhanh . Vì bạn muốn sử dụng hàm băm để bảo vệ, tốt hơn hết bạn nên sử dụng hàm băm chậm hơn. Ví dụ, hãy xem Bcrypt , PBKDF2 hoặc Scrypt .

chỉnh sửa : sau khi quan sát, chúng ta hãy thử xem một số điểm (xin lỗi, giải thích dài để đi đến cuối cùng, bởi vì nó có thể giúp người khác tìm kiếm câu trả lời tương tự):

Nếu hệ thống của bạn an toàn, như không ai sẽ có quyền truy cập vào mật khẩu được lưu trữ, bạn sẽ không cần băm. Mật khẩu sẽ là bí mật, không ai có được nó.

Nhưng không ai có thể đảm bảo rằng cơ sở dữ liệu với mật khẩu sẽ bị đánh cắp. Ăn cắp cơ sở dữ liệu, có tất cả các mật khẩu. Ok, hệ thống của bạn và công ty của bạn sẽ chịu tất cả các hậu quả của nó. Vì vậy, chúng tôi có thể cố gắng tránh rò rỉ mật khẩu này.

THÔNG BÁO rằng chúng tôi không lo lắng về các cuộc tấn công trực tuyến trong thời điểm này. Đối với một cuộc tấn công trực tuyến, giải pháp tốt nhất là làm chậm sau khi mật khẩu xấu, khóa tài khoản sau một số lần thử, v.v. Và điều đó không quan trọng bằng cách bạn mã hóa, băm, lưu trữ, v.v., mật khẩu của bạn. Tấn công trực tuyến là một vấn đề làm chậm các đầu vào mật khẩu .

Vì vậy, trở lại don't let them take my plain passwordsvấn đề. Câu trả lời rất đơn giản: đừng lưu trữ chúng dưới dạng văn bản đơn giản. OK đã nhận nó.

Làm thế nào để tránh điều đó?

Mã hóa mật khẩu (?). Nhưng, như bạn biết, nếu bạn mã hóa nó, bạn có thể giải mã lại, nếu bạn có khóa thích hợp. Và bạn sẽ kết thúc với vấn đề "nơi cất giấu" chìa khóa. Hum, không tốt, vì họ có cơ sở dữ liệu của bạn, họ có thể lấy chìa khóa của bạn. Ok, chúng ta đừng sử dụng nó.

Vì vậy, một cách tiếp cận khác: hãy chuyển đổi mật khẩu theo thứ khác không thể đảo ngược và lưu trữ nó. Và để xác minh xem mật khẩu được cung cấp có đúng không, chúng tôi thực hiện lại quy trình tương tự và kiểm tra xem hai giá trị tranformed có khớp hay không. Nếu chúng khớp = mật khẩu tốt đã được cung cấp.

Ok, cho đến nay rất tốt. Hãy sử dụng một số băm MD5 trong mật khẩu. Nhưng ... nếu ai đó có giá trị băm mật khẩu được lưu trữ của chúng tôi, anh ta có thể có rất nhiều sức mạnh máy tính để tính băm MD5 của mọi mật khẩu có thể (lực lượng vũ phu), vì vậy anh ta có thể tìm thấy mật khẩu ban đầu. Hoặc, thậm chí tệ nhất, anh ta có thể lưu trữ tất cả MD5 từ tất cả các kết hợp ký tự và dễ dàng tìm thấy mật khẩu. Vì vậy, hãy thực hiện nhiều lần lặp, điều HASH (HASH (HASH ())), để làm cho nó khó hơn, vì sẽ mất nhiều thời gian hơn.

Nhưng ngay cả điều đó có thể được lưu hành, bảng cầu vồng đã được tạo ra chính xác để tăng tốc chống lại loại bảo vệ này.

Vì vậy, hãy sử dụng một ít muối trên nó. Bằng cách này, tại mỗi tương tác, muối được sử dụng lại. Một người cố gắng tấn công mật khẩu của bạn sẽ phải tạo bảng cầu vồng xem xét rằng muối được thêm vào mỗi lần. Và khi anh ta tạo bảng cầu vồng đó, vì nó được tạo bằng một muối, anh ta sẽ phải tính toán lại với muối kia, vì vậy anh ta sẽ phải dành thời gian cho mỗi mật khẩu (= mỗi muối). Muối sẽ không thêm "phức tạp" hơn vào mật khẩu, nó sẽ khiến kẻ tấn công mất thời gian tạo bảng cầu vồng, nếu bạn sử dụng một muối cho mỗi mật khẩu, thì bảng từ một muối sẽ vô dụng với mật khẩu khác.

Và sử dụng nhiều hơn một hàm băm sẽ giúp gì ở đây? Không. Người tạo ra một cuộc tấn công cầu vồng cụ thể sẽ có thể tạo ra nó bằng cách sử dụng một hoặc nhiều băm.

Và việc sử dụng nhiều hơn một hàm băm có thể dẫn bạn đến một vấn đề: nó an toàn như hàm băm yếu nhất bạn sử dụng. Nếu ai đó tìm thấy xung đột trong một thuật toán băm, thì đó là hàm băm sẽ được khai thác, tại bất kỳ điểm nào của quá trình lặp, để phá mật khẩu. Vì vậy, bạn không đạt được bất cứ điều gì bằng cách sử dụng nhiều thuật toán băm hơn, tốt hơn là chỉ chọn một thuật toán tốt. và sử dụng nó. Và nếu yuo từng nghe rằng nó đã bị hỏng, hãy nghĩ cách bạn sẽ thay đổi nó trong ứng dụng của mình.

Và tại sao sử dụng bcrypt hoặc một cái gì đó tương tự (bạn nói bạn sử dụng nó): bởi vì kẻ tấn công sẽ phải mất nhiều thời gian hơn để tạo các bảng. Đó là lý do tại sao sử dụng MD5 + chờ đợi (3 giây) không giúp ích gì: dù sao cuộc tấn công sẽ ngoại tuyến, vì vậy kẻ tấn công có thể tạo các bảng mà không bị trì hoãn (3 giây).


2
Úi! Xin lỗi, nhận xét của tôi (về việc cố tình làm cho hàm băm chậm hơn thông qua thời gian chờ) không có nghĩa là phải nghiêm túc ... Tôi nghĩ rằng gần đây tôi đã đọc quá nhiều Dilbert.
Thất vọngWithFormsDesigner

2
sha (sha (sha (...))) không an toàn hơn sha. Nếu entropy của hàm sha không tối đa, thì điều này thực sự kém an toàn.
deadalnix

1
@deadalnix: điều quan trọng là phải đề cập đến việc nó không giúp khôi phục mật khẩu ban đầu dễ dàng hơn, nhưng nó giúp việc tạo mật khẩu va chạm dễ dàng hơn, đó là tất cả những gì bắt buộc.
Bryan Boettcher

1
@deadalnix, tôi đọc bình luận đó bằng giọng nói của Dale Gribble .
nhộn

1
@deadalnix: mục tiêu của sha (sha (sha ())) không, và không bao giờ, để thêm entropy. Entropy chỉ được thực hiện bởi người dùng ban đầu chọn mật khẩu của mình, mọi thứ khác (băm, muối, v.v.) chỉ để làm chậm cuộc tấn công vũ phu. Nếu ai đó có thể lấy cơ sở dữ liệu của bạn chứa mật khẩu, anh ta có thể cũng sẽ nhận được mã được sử dụng để băm mật khẩu, do đó, bất kỳ loại muối mã hóa cứng nào cũng được biết đến
woliveirajr

-1

Hiểu biết của tôi là sử dụng nhiều thuật toán băm là để đánh bại các bảng cầu vồng . Sử dụng một loại muối tốt cũng có tác dụng, nhưng tôi đoán đó là cấp độ bảo vệ thứ hai.


4
Vâng, điều này không thay đổi nhiều. Fucntion «nhiều hàm băm» có thể được xem là một và được xử lý như vậy.
deadalnix

2
Sử dụng nhiều kỹ thuật băm hoặc lặp lại không có gì để đánh bại các bảng cầu vồng. Nếu kẻ tấn công có cơ sở dữ liệu của bạn và có phương thức được sử dụng để tạo băm, thì kẻ tấn công có thể tạo bảng cầu vồng để tấn công tất cả mật khẩu trong cơ sở dữ liệu. SALTS ngăn chặn các cuộc tấn công bảng cầu vồng vì chúng ngăn chặn kẻ tấn công tạo ra một từ điển tra cứu duy nhất để tấn công, giả sử, tất cả mật khẩu từ 8 ký tự trở xuống.
Erik

-1

Điều này không an toàn hơn. Tuy nhiên, bạn có một giao thức nhận dạng dựa trên hàm băm nhiều lần với cùng một chức năng.

Điều này đi theo cách đó. Giá trị được lưu là hash ^ n (pass) trong máy tính A. A yêu cầu B xác thực và cung cấp cho B số nguyên n. B thực hiện băm tính toán ^ (n-1) (đạt) và gửi lại cho A.

Kiểm tra xem băm (băm ^ (n-1) (pass)) == hash ^ n (pass). Nếu nó là sự thật, thì việc xác thực được thực hiện. Nhưng sau đó, A lưu trữ băm ^ (n-1) (đạt) và xác thực tiếp theo, sẽ cung cấp cho B n-1 thay vì n.

Điều này đảm bảo rằng mật khẩu không bao giờ được trao đổi rõ ràng, rằng A không bao giờ biết mật khẩu là gì và xác thực được bảo vệ bằng cách phát lại. Tuy nhiên, điều này có nhược điểm là yêu cầu mật khẩu với vòng đời hữu hạn. Khi n đạt giá trị 2, mật khẩu mới phải được chọn sau khi xác thực.

Một cách sử dụng khác của nhiều hàm băm là công cụ HMAC, để đảm bảo tính xác thực và tính toàn vẹn của một yêu cầu. Để biết thêm về HMAC, hãy xem http://en.wikipedia.org/wiki/HMAC .

Hầu hết việc sử dụng nhiều hàm băm trong thế giới thực là quá mức cần thiết. Trong trường hợp của bạn, nó có vẻ là. Lưu ý rằng nếu bạn sử dụng một số hàm băm, tất cả chúng sẽ không có cùng một entropy, do đó điều này làm giảm sức mạnh của hàm băm. Ví dụ, md5 có ít entropy hơn sha1, vì vậy sử dụng sha1 trên md5 sẽ không cải thiện độ mạnh của hàm băm. Sức mạnh nói chung sẽ bằng với sức mạnh của hàm băm yếu hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.