2013-03-19 43 views
21

Tôi đang triển khai dịch vụ web REST bằng C# sẽ được lưu trữ trên Azure dưới dạng dịch vụ đám mây. Vì nó là một dịch vụ REST, nó là không trạng thái và do đó không có cookie hoặc trạng thái phiên.Thực hiện mã thông báo xác thực dịch vụ web REST

Dịch vụ web chỉ có thể được truy cập qua HTTPS (Chứng chỉ do StartSSL.com cung cấp).

Khi người dùng đăng nhập thành công vào dịch vụ, họ sẽ nhận được mã thông báo bảo mật. Mã thông báo này sẽ cung cấp xác thực trong các liên lạc trong tương lai.

Mã thông báo sẽ chứa dấu thời gian, địa chỉ người dùng và địa chỉ IP của ứng dụng khách.

Mọi giao tiếp sẽ chỉ xảy ra qua HTTPS vì vậy tôi không quan tâm đến mã thông báo bị chặn và sử dụng trong các cuộc tấn công phát lại; mã thông báo sẽ hết hạn.

Vì đây là dịch vụ đối mặt công khai, tuy nhiên tôi lo ngại rằng ai đó có thể đăng ký dịch vụ, đăng nhập và sau đó sửa đổi mã thông báo mà họ nhận được để truy cập vào tài khoản của người dùng khác.

Tôi tự hỏi làm thế nào tốt nhất để bảo mật nội dung của mã thông báo và cũng xác minh rằng nó không bị giả mạo.

tôi có kế hoạch làm những điều sau đây để bảo đảm mã thông báo:

Các khách hàng thành công đăng nhập vào các dịch vụ và các dịch vụ thực hiện:

  1. Tạo một giá trị ngẫu nhiên và băm nó với SHA256 1000 lần.
  2. Tạo khóa phiên một lần từ khóa cá nhân + giá trị ngẫu nhiên được băm.
  3. Băm khóa phiên với SHA256 1000 lần và sau đó sử dụng khóa này để mã hóa mã thông báo
  4. Sử dụng khóa riêng để ký mã thông báo được mã hóa bằng RSA.
  5. Gửi mã thông báo được mã hóa + chữ ký + giá trị ngẫu nhiên được băm cho khách hàng trong gói JSON không được mã hóa.

Khi khách hàng gọi dịch vụ, nó sẽ gửi mã thông báo mã hóa và chữ ký trong gói JSON không được mã hóa đến dịch vụ. Dịch vụ này sẽ

  1. Tạo lại khóa phiên từ khóa riêng + giá trị ngẫu nhiên băm
  2. Sử dụng khóa riêng để xác minh chữ ký
  3. Sử dụng phím phiên băm để giải mã token
  4. Kiểm tra xem mã thông báo chưa hết hạn
  5. Tiếp tục với thao tác được yêu cầu ...

Tôi thực sự không biết gì về mã hóa vì vậy tôi có một số câu hỏi:

  1. Điều này có đủ hay quá mức không?
  2. Tôi đọc điều đó để phát hiện giả mạo tôi nên bao gồm HMAC với mã thông báo. Vì tôi ký hợp đồng với khóa riêng, tôi có cần HMAC không?
  3. Tôi có nên sử dụng Rijndael thay vì RSA không?
  4. Nếu Rijndael được ưu tiên, IV có được yêu cầu để giải mã không? tức là tôi có thể vứt nó đi hoặc tôi có cần gửi mã thông báo được mã hóa không? ví dụ. Mã hóa được mã hóa + HMAC + IV + giá trị ngẫu nhiên được băm.

Vì mọi giao tiếp diễn ra qua HTTPS gói JSON không mã hóa không thực sự không được mã hóa cho đến khi nó đến được máy khách.

Ngoài ra, tôi có thể muốn triển khai lại dịch vụ trong PHP sau này để tất cả điều này cũng cần phải thực hiện được trong PHP.

Cảm ơn sự giúp đỡ của bạn

Trả lời

24

Bạn đang thực sự suy nghĩ quá mức. Trung thực, bảo mật mã thông báo tốt nhất dựa trên tính ngẫu nhiên hoặc chính xác hơn không thể đoán trước. Các thẻ tốt nhất là hoàn toàn ngẫu nhiên. Bạn đúng rằng một mối quan tâm là người dùng sẽ sửa đổi mã thông báo của họ và sử dụng nó để truy cập vào tài khoản của người khác. Đây là một cuộc tấn công phổ biến được gọi là "phiên ăn cắp." Cuộc tấn công này gần như không thể khi các thẻ được tạo ngẫu nhiên và hết hạn ở phía máy chủ. Sử dụng thông tin của người dùng như IP và/hoặc dấu thời gian là thực hành không tốt vì nó cải thiện khả năng dự đoán. Tôi đã thực hiện một cuộc tấn công ở trường đại học đã đoán thành công các thẻ hoạt động dựa trên tem thời gian máy chủ tính bằng micro giây. Tác giả của ứng dụng suy nghĩ micro giây sẽ thay đổi đủ nhanh mà họ sẽ không thể đoán trước, nhưng đó không phải là trường hợp. Bạn nên lưu ý rằng khi người dùng ở phía sau máy chủ proxy, proxy đôi khi sẽ xem yêu cầu SSL của họ ở dạng văn bản thuần túy (vì lý do bảo mật, nhiều proxy sẽ thực hiện kiểm tra gói sâu). Vì lý do này, tốt là bạn hết hạn phiên. Nếu bạn không phải là người dùng của bạn sẽ dễ bị tấn công như vậy, và cũng có thể là XSS và CSRF.

RSA hoặc Rijndael phải đủ lớn, cung cấp độ dài khóa hợp lý. Ngoài ra, bạn nên sử dụng một HMAC với mã thông báo để ngăn chặn giả mạo, ngay cả khi bạn đang ký nó. Về lý thuyết nó sẽ là thừa, vì bạn đang ký với một khóa riêng. Tuy nhiên, HMAC được kiểm tra rất tốt và việc triển khai cơ chế ký kết của bạn có thể bị thiếu sót. Vì lý do đó, tốt hơn nên sử dụng HMAC. Bạn sẽ ngạc nhiên về việc có bao nhiêu "triển khai bảo mật" của riêng bạn có những sai sót dẫn họ đến thỏa hiệp.

Bạn có vẻ khá hiểu biết về bảo mật. Hãy tiếp tục phát huy! Chúng ta cần những người có ý thức bảo mật hơn trong thế giới này.

EDIT:

Nó được coi là an toàn để bao gồm timestamps/ID người dùng trong token miễn là họ được mã hóa với một đối xứng khóa bí mật mạnh mẽ (như AES, Blowfish, vv) mà chỉ có máy chủ có và miễn là mã thông báo bao gồm một băm bằng chứng giả mạo với nó như HMAC, được mã hóa bằng khóa bí mật cùng với ID người dùng/dấu thời gian. Hàm băm đảm bảo tính toàn vẹn và mã hóa đảm bảo tính bảo mật.

Nếu bạn không bao gồm HMAC (hoặc mã băm khác) trong mã hóa, thì người dùng có thể giả mạo mã thông báo được mã hóa và giải mã cho một thứ gì đó hợp lệ. Tôi đã tấn công vào một máy chủ trong đó User ID và tem thời gian được mã hóa và được sử dụng như một mã thông báo mà không có một băm. Bằng cách thay đổi một ký tự ngẫu nhiên trong chuỗi, tôi có thể thay đổi ID người dùng của mình từ một cái gì đó như 58762 thành 58531. Trong khi tôi không thể chọn ID người dùng "mới", tôi có thể truy cập tài khoản của người khác. , như là một phần của khóa học).

Cách khác là sử dụng giá trị mã thông báo hoàn toàn ngẫu nhiên và ánh xạ nó ở phía máy chủ với dấu người dùng/dấu thời gian được lưu trữ (nằm ở phía máy chủ và do đó nằm ngoài kiểm soát khách hàng). Điều này cần nhiều bộ nhớ hơn và sức mạnh xử lý, nhưng an toàn hơn. Đây là một quyết định bạn sẽ phải thực hiện trên cơ sở từng trường hợp.

Như để sử dụng lại/lấy chìa khóa từ IV và các phím khác, điều này thường là ok, miễn là các phím chỉ có giá trị trong một khoảng thời gian ngắn. Về mặt toán học, dường như không ai có thể phá vỡ chúng. Có thể tuy nhiên. Nếu bạn muốn đi con đường hoang tưởng (mà tôi thường làm), tạo ra tất cả các phím mới ngẫu nhiên.

+0

Cảm ơn vì điều đó. Tôi đã quyết định sử dụng Rijndael và HMAC nhưng vẫn cố gắng để có được đầu của tôi xung quanh nó. Tôi có thể sử dụng IV để lấy khóa phiên từ khóa chính không? Tôi cũng có thể sử dụng khóa phiên tương tự cho HMAC hoặc tôi có cần lấy một khóa mới từ khóa phiên hiện tại không? Nếu tôi cần một khóa mới cho HMAC tôi có thể sử dụng IV hiện tại cho điều này hay tôi cần một giá trị ngẫu nhiên mới không? Cuối cùng bạn đã đề cập rằng tôi không nên mã hóa dấu thời gian với ID người dùng, làm thế nào tôi có thể biết rằng mã thông báo đã hết hạn? vì tôi không thể lưu trữ một bản ghi phiên trong cơ sở dữ liệu. Cảm ơn một lần nữa. –

+0

Câu hỏi hay. Tôi sẽ cập nhật câu trả lời với một số thông tin bổ sung –

+0

Ok tôi nhận được tất cả những điều đó. Vì vậy, HMAC được tính toán từ dữ liệu không được mã hóa và sau đó được mã hóa với dữ liệu? Tôi có cần lưu trữ HMAC trên máy chủ để so sánh sau hoặc tôi có thể mã hóa mã thông báo và sau đó tính toán HMAC từ dữ liệu chưa được mã hóa và so sánh nó với HMAC đã được mã hóa với dữ liệu không? –

Các vấn đề liên quan