Các thuật toán băm mật khẩu thường được sử dụng hoạt động như thế này ngày nay: Muối mật khẩu và đưa nó vào một KDF. Ví dụ: sử dụng PBKDF2-HMAC-SHA1, quá trình băm mật khẩu là DK = PBKDF2(HMAC, Password, Salt, ...)
. Bởi vì HMAC là một hàm băm 2 vòng với các phím được đệm và SHA1 là một chuỗi các hoán vị, dịch chuyển, xoay và hoạt động theo bit, về cơ bản, toàn bộ quá trình là một số thao tác cơ bản được tổ chức theo một cách nhất định. Về cơ bản, điều đó không rõ ràng về việc họ thực sự khó tính toán như thế nào. Đó có lẽ là lý do tại sao các hàm một chiều vẫn là một niềm tin và chúng ta đã thấy một số hàm băm mật mã quan trọng trong lịch sử trở nên không an toàn và không được dùng nữa.
Tôi đã tự hỏi liệu có thể tận dụng các vấn đề hoàn chỉnh của NP để băm mật khẩu theo cách hoàn toàn mới hay không, hy vọng sẽ mang lại cho nó một nền tảng lý thuyết vững chắc hơn. Ý tưởng chính là, giả sử P! = NP (nếu P == NP thì không có OWF nên các sơ đồ hiện tại cũng bị phá vỡ), là một vấn đề NPC có nghĩa là câu trả lời dễ xác minh nhưng khó tính toán. Khách sạn này phù hợp với các yêu cầu băm mật khẩu. Nếu chúng tôi xem mật khẩu là câu trả lời cho vấn đề NPC, thì chúng tôi có thể lưu trữ sự cố NPC dưới dạng hàm băm của mật khẩu để chống lại các cuộc tấn công ngoại tuyến: Thật dễ dàng để xác minh mật khẩu, nhưng khó bị bẻ khóa.
Hãy cẩn thận, cùng một mật khẩu có thể được ánh xạ tới nhiều trường hợp của một vấn đề NPC, có lẽ không phải tất cả chúng đều khó giải quyết. Bước đầu tiên trong nghiên cứu này, tôi đã cố gắng diễn giải một chuỗi nhị phân như là một câu trả lời cho vấn đề 3-SAT và để xây dựng một trường hợp của vấn đề 3-SAT mà chuỗi nhị phân là một giải pháp. Ở dạng đơn giản nhất, chuỗi nhị phân có 3 bit: x_0, x_1, x_2. Sau đó, có 2 ^ 3 == 8 mệnh đề:
000 ( (x_0) v (x_1) v (x_2) )
--------------------------------------
001 ( (x_0) v (x_1) v NOT(x_2) )
010 ( (x_0) v NOT(x_1) v (x_2) )
011 ( (x_0) v NOT(x_1) v NOT(x_2) )
100 ( NOT(x_0) v (x_1) v (x_2) )
101 ( NOT(x_0) v (x_1) v NOT(x_2) )
110 ( NOT(x_0) v NOT(x_1) v (x_2) )
111 ( NOT(x_0) v NOT(x_1) v NOT(x_2) )
Giả sử chuỗi nhị phân là 000. Sau đó, chỉ có 1 trong 8 mệnh đề là sai (đầu tiên). Nếu chúng ta loại bỏ mệnh đề đầu tiên và AND 7 mệnh đề còn lại, thì 000 là một giải pháp của công thức kết quả. Vì vậy, nếu chúng tôi lưu trữ công thức, sau đó chúng tôi có thể xác minh 000.
Vấn đề là, đối với chuỗi 3 bit, nếu bạn thấy 7 mệnh đề khác nhau ở đó, thì bạn sẽ biết ngay cái nào bị thiếu và điều đó sẽ tiết lộ các bit.
Vì vậy, sau đó tôi quyết định loại bỏ 3 trong số chúng, chỉ giữ 4 số được đánh dấu bởi 001, 010, 100 và 111. Điều này đôi khi đưa ra các va chạm nhưng làm cho việc giải quyết vấn đề trở nên ít tầm thường hơn. Các va chạm không phải lúc nào cũng xảy ra, nhưng liệu chúng chắc chắn sẽ biến mất khi đầu vào có nhiều bit hơn chưa được biết.
Biên tập. Trong trường hợp chung trong đó chuỗi nhị phân có thể là bất kỳ (000, 001, ..., 111), vẫn còn 8 mệnh đề trong đó 7 mệnh đề đúng và 1 là sai. Chọn 4 mệnh đề cho giá trị thật (001, 010, 100, 111). Điều này được phản ánh trong việc thực hiện nguyên mẫu dưới đây.
Biên tập. Như câu trả lời được hiển thị bởi @DW bên dưới, phương pháp chọn mệnh đề này vẫn có thể dẫn đến quá nhiều mệnh đề trên một tập hợp các biến đã cho, có thể nhanh chóng thu hẹp giá trị của chúng. Có các phương pháp khác nhau để chọn các mệnh đề trong tổng số các mệnh đề 7 * C (n, 3). Ví dụ: Chọn một số mệnh đề khác nhau từ một tập hợp các biến đã cho và chỉ thực hiện điều đó cho các biến liền kề ((x_0, x_1, x_2), (x_1, x_2, x_3), (x_2, x_3, x_4), .. .) và do đó tạo thành một chu kỳ thay vì một cụm. Phương pháp này có thể không hoạt động tốt vì theo trực giác, bạn có thể thử các bài tập sử dụng cảm ứng để kiểm tra xem tất cả các mệnh đề có thể được thỏa mãn hay không. Vì vậy, để làm cho nó đơn giản giải thích cấu trúc tổng thể, hãy sử dụng phương thức hiện tại.
Số mệnh đề cho chuỗi n bit là 4 * C (n, 3) = 4 * n * (n - 1) * (n - 2) / 6 = O (n ^ 3), có nghĩa là kích thước của hàm băm là đa thức về kích thước của mật khẩu.
Có một triển khai nguyên mẫu trong Python ở đây . Nó tạo ra một trường hợp vấn đề 3-SAT từ một chuỗi nhị phân đầu vào của người dùng.
Sau phần giới thiệu dài này, cuối cùng câu hỏi của tôi:
Liệu cấu trúc trên (như được thực hiện trong nguyên mẫu) có hoạt động như băm mật khẩu an toàn, hoặc ít nhất là trông có triển vọng, có thể được sửa đổi, v.v.? Nếu không thì thất bại ở đâu?
Vì chúng ta có các mệnh đề 7 * C (n, 3) để lựa chọn, nên có thể tìm một cách khác để xây dựng một thể hiện 3-SAT an toàn phù hợp để sử dụng làm hàm băm mật khẩu, có thể với sự trợ giúp của ngẫu nhiên không?
Có công việc tương tự nào đang cố gắng tận dụng tính hoàn chỉnh của NP để thiết kế các lược đồ băm mật khẩu an toàn đã được chứng minh và đã có một số kết quả (tích cực hay tiêu cực) không? Một số phần giới thiệu và liên kết sẽ rất được hoan nghênh.
Biên tập. Tôi chấp nhận câu trả lời dưới đây của @DW, người đầu tiên trả lời và đưa ra những hiểu biết tuyệt vời về cấu trúc vấn đề cũng như các tài nguyên hữu ích. Lược đồ lựa chọn mệnh đề ngây thơ được giới thiệu ở đây (như được triển khai trong nguyên mẫu Python) dường như không hoạt động vì có thể nhanh chóng thu hẹp các phép gán biến trong các nhóm nhỏ. Tuy nhiên, vấn đề vẫn còn mở vì tôi chưa thấy một bằng chứng chính thức nào cho thấy việc giảm NPC-to-PasswordHashing như vậy sẽ không hiệu quả. Ngay cả đối với bài toán giảm 3-SAT cụ thể này, có thể có nhiều cách chọn mệnh đề khác nhau mà tôi không muốn liệt kê ở đây. Vì vậy, bất kỳ cập nhật và thảo luận vẫn rất được hoan nghênh.