Các phương pháp hay nhất để tạo mã thông báo OAuth?


100

Tôi nhận thấy rằng thông số OAuth không chỉ định bất kỳ điều gì về nguồn gốc của mã ConsumerKey, ConsumerSecret, AccessToken, RequestToken, TokenSecret hoặc Verifier, nhưng tôi tò mò liệu có bất kỳ phương pháp hay nhất nào để tạo mã thông báo an toàn đáng kể (đặc biệt là Token / Kết hợp bí mật).

Như tôi thấy, có một số cách tiếp cận để tạo mã thông báo:

  1. Chỉ cần sử dụng các byte ngẫu nhiên, lưu trữ trong DB được liên kết với người tiêu dùng / người dùng
  2. Băm một số dữ liệu người dùng / người dùng cụ thể, lưu trữ trong DB được liên kết với khách hàng / người dùng
  3. Mã hóa dữ liệu người dùng / người tiêu dùng cụ thể

Ưu điểm của (1) là cơ sở dữ liệu là nguồn duy nhất của thông tin có vẻ an toàn nhất. Sẽ khó hơn để tấn công chống lại (2) hoặc (3).

Băm dữ liệu thực (2) sẽ cho phép tạo lại mã thông báo từ dữ liệu có lẽ đã biết. Có thể không thực sự cung cấp bất kỳ lợi ích nào cho (1) vì dù sao cũng cần lưu trữ / tra cứu. Nhiều CPU hơn (1).

Mã hóa dữ liệu thực (3) sẽ cho phép giải mã để biết thông tin. Điều này sẽ yêu cầu ít bộ nhớ hơn và có khả năng ít tra cứu hơn (1) & (2), nhưng cũng có khả năng kém an toàn hơn.

Có bất kỳ cách tiếp cận / ưu điểm / nhược điểm nào khác cần được xem xét không?

CHỈNH SỬA: một cân nhắc khác là PHẢI có một số loại giá trị ngẫu nhiên trong Mã thông báo vì phải tồn tại khả năng hết hạn và phát hành lại mã thông báo mới để nó không được chỉ bao gồm dữ liệu thực.

Theo dõi các câu hỏi :

Có độ dài mã thông báo tối thiểu để đảm bảo an toàn về mặt mật mã không? Theo tôi hiểu, Token Secrets dài hơn sẽ tạo ra nhiều chữ ký an toàn hơn. Cách hiểu này có đúng không?

Có lợi thế nào khi sử dụng một mã hóa cụ thể so với một mã hóa khác từ góc độ băm không? Ví dụ: tôi thấy rất nhiều API sử dụng mã hóa hex (ví dụ: chuỗi GUID). Trong thuật toán ký OAuth, Mã thông báo được sử dụng dưới dạng một chuỗi. Với một chuỗi hex, tập ký tự có sẵn sẽ nhỏ hơn nhiều (dễ đoán hơn) so với mã hóa Base64. Đối với tôi, dường như đối với hai chuỗi có độ dài bằng nhau, chuỗi nào có bộ ký tự lớn hơn sẽ có phân phối băm tốt hơn / rộng hơn. Điều này có vẻ như với tôi rằng nó sẽ cải thiện bảo mật. Giả thiết này có đúng không?

Đặc tả OAuth đặt ra vấn đề này rất chính xác trong 11.10 Entropy of Secrets .


Tại sao mã hóa? Hàm băm chưa đủ tốt? Nếu chỉ băm là đủ tốt cho mật khẩu, thì không phải tốt hơn cho các mã thông báo truy cập lâu hơn?
AlikElzin-kilaka

Đã 7,5 năm kể từ khi tôi đặt câu hỏi. Tôi thực sự không thể nhớ.
mckamey

1
Đọc lại, băm và mã hóa là hai cách tiếp cận khác nhau được đề xuất. Mã hóa sẽ cho phép máy chủ nhận một số thông tin mà không cần tra cứu DB. Đó là một sự đánh đổi giữa nhiều thứ.
mckamey

Câu trả lời:


93

OAuth không nói gì về mã thông báo ngoại trừ việc nó có một bí mật liên quan đến nó. Vì vậy, tất cả các kế hoạch bạn đã đề cập sẽ hoạt động. Mã thông báo của chúng tôi phát triển khi các trang web trở nên lớn hơn. Đây là các phiên bản chúng tôi đã sử dụng trước đây,

  1. Mã thông báo đầu tiên của chúng tôi là BLOB được mã hóa với tên người dùng, mã thông báo bí mật và hết hạn, v.v. Vấn đề là chúng tôi không thể thu hồi mã thông báo mà không có bất kỳ hồ sơ nào trên máy chủ.

  2. Vì vậy, chúng tôi đã thay đổi nó để lưu trữ mọi thứ trong cơ sở dữ liệu và mã thông báo chỉ đơn giản là một số ngẫu nhiên được sử dụng làm khóa cho cơ sở dữ liệu. Nó có chỉ mục tên người dùng nên dễ dàng liệt kê tất cả các mã thông báo cho người dùng và thu hồi nó.

  3. Chúng tôi nhận được khá ít hoạt động hack. Với số ngẫu nhiên, chúng ta phải vào cơ sở dữ liệu để biết mã thông báo có hợp lệ hay không. Vì vậy, chúng tôi đã quay lại BLOB được mã hóa một lần nữa. Lần này, mã thông báo chỉ chứa giá trị được mã hóa của khóa và hết hạn. Vì vậy, chúng tôi có thể phát hiện các mã thông báo không hợp lệ hoặc hết hạn mà không cần đi đến cơ sở dữ liệu.

Một số chi tiết triển khai có thể giúp bạn,

  1. Thêm một phiên bản trong mã thông báo để bạn có thể thay đổi định dạng mã thông báo mà không phá vỡ các định dạng hiện có. Tất cả mã thông báo của chúng tôi có byte đầu tiên là phiên bản.
  2. Sử dụng phiên bản Base64 an toàn cho URL để mã hóa BLOB, do đó bạn không phải đối phó với các vấn đề mã hóa URL, điều này làm cho việc gỡ lỗi khó khăn hơn với chữ ký OAuth, vì bạn có thể thấy ba cơ sở được mã hóa.

2
Cảm ơn vô cùng. Ý tưởng về phiên bản là một ý tưởng tốt. Tôi đã sử dụng Base64 thân thiện với URL, nhưng tôi ước mình có một mã hóa chữ-số chặt chẽ để đọc dễ dàng hơn.
mckamey

Chưa từng nghĩ đến điều đó trước đây, rất thú vị! Tôi đã lên kế hoạch về bộ nhớ đệm khóa APC để giữ cho DB tải không liên tục trước khi tôi đọc bài này. Vẫn không chắc liệu điều này có thể không chậm hơn APC tra cứu bộ nhớ dùng chung hay không (ít nhất là ở yêu cầu thứ 2, thứ 3, v.v. trong khoảng thời gian hợp lý).
Philzen
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.