Một điều mà tôi không thấy được đề cập ở đây, mặc dù nó là phần mở rộng cho câu trả lời của Marcus Adams, đó là bạn không nên sử dụng một phần thông tin để vừa xác định vừa xác thực người dùng nếu có khả năng xảy ra các cuộc tấn công định thời , điều này có thể sử dụng sự khác biệt về thời gian phản hồi để đoán xem so sánh chuỗi đã đi được bao xa.
Nếu bạn đang sử dụng một hệ thống sử dụng "khóa" để tra cứu người dùng hoặc thông tin đăng nhập, thì phần thông tin đó có thể được đoán dần dần theo thời gian bằng cách gửi hàng nghìn yêu cầu và kiểm tra thời gian cơ sở dữ liệu của bạn có thể tìm thấy (hay không tìm) một bản ghi. Điều này đặc biệt đúng nếu "khóa" được lưu trữ trong văn bản rõ ràng thay vì băm một chiều của khóa. Bạn muốn lưu trữ các khóa của người dùng ở dạng văn bản rõ ràng hoặc được mã hóa đối xứng nếu bạn cần có thể hiển thị lại khóa cho người dùng.
Bằng cách có phần thông tin thứ hai hoặc "bí mật", trước tiên bạn có thể tra cứu người dùng hoặc thông tin đăng nhập bằng cách sử dụng "khóa", có thể dễ bị tấn công thời gian, sau đó sử dụng chức năng so sánh an toàn về thời gian để kiểm tra giá trị của bí mật".
Đây là cách triển khai hàm đó của Python:
https://github.com/python/cpython/blob/cd8295ff758891f21084a6a5ad3403d35dda38f7/Modules/_operator.c#L727
Và nó được hiển thị trong hmac
lib (và có thể là những người khác):
https://docs.python.org/3/library/hmac.html#hmac.compare_digest
Một điều cần lưu ý ở đây là tôi không nghĩ rằng kiểu tấn công này sẽ hoạt động trên các giá trị được băm hoặc mã hóa trước khi tra cứu, bởi vì các giá trị được so sánh thay đổi ngẫu nhiên mỗi khi một ký tự trong chuỗi đầu vào thay đổi. Tôi tìm thấy một lời giải thích tốt về điều này ở đây .
Các giải pháp để lưu trữ khóa API sau đó sẽ là:
- Sử dụng khóa và bí mật riêng biệt, sử dụng khóa để tra cứu hồ sơ và sử dụng so sánh an toàn về thời gian để kiểm tra bí mật. Điều này cho phép bạn hiển thị lại chìa khóa và bí mật cho người dùng.
- Sử dụng khóa và bí mật riêng biệt, sử dụng mã hóa đối xứng, xác định đối với bí mật và thực hiện so sánh thông thường các bí mật được mã hóa. Điều này cho phép bạn hiển thị lại khóa và bí mật cho người dùng, đồng thời có thể giúp bạn không phải thực hiện so sánh an toàn về thời gian.
- Sử dụng một khóa và bí mật riêng biệt, hiển thị bí mật, băm và lưu trữ, sau đó thực hiện so sánh bình thường với bí mật đã băm. Điều này loại bỏ sự cần thiết phải sử dụng mã hóa hai chiều và có thêm lợi ích là giữ bí mật của bạn an toàn nếu hệ thống bị xâm phạm. Nó có nhược điểm là bạn không thể hiển thị lại bí mật cho người dùng.
- Sử dụng một khóa duy nhất , hiển thị nó cho người dùng một lần, băm nó, sau đó thực hiện tra cứu bình thường đối với khóa được băm hoặc mã hóa. Điều này sử dụng một phím duy nhất, nhưng nó không thể hiển thị lại cho người dùng. Có lợi ích trong việc giữ khóa an toàn nếu hệ thống bị xâm phạm.
- Sử dụng một khóa duy nhất , hiển thị nó cho người dùng một lần, mã hóa nó và thực hiện tra cứu thông thường về bí mật được mã hóa. Có thể được hiển thị lại cho người dùng, nhưng phải trả giá là có các khóa dễ bị tổn thương nếu hệ thống của họ bị xâm phạm.
Trong số này, tôi nghĩ rằng 3 là sự cân bằng tốt nhất về bảo mật và tiện lợi. Tôi đã thấy điều này được triển khai trên nhiều trang web khi nhận được chìa khóa.
Ngoài ra, tôi mời bất kỳ chuyên gia bảo mật thực tế nào phê bình câu trả lời này. Tôi chỉ muốn đưa điều này ra khỏi đó như một điểm thảo luận khác.