Cập nhật:
Tôi đã thêm liên kết này vào câu trả lời khác của mình về cách sử dụng xác thực JWT cho API Web ASP.NET tại đây cho bất kỳ ai quan tâm đến JWT.
Chúng tôi đã quản lý để áp dụng xác thực HMAC cho API Web bảo mật và nó hoạt động tốt. Xác thực HMAC sử dụng một khóa bí mật cho mỗi người tiêu dùng mà cả người tiêu dùng và máy chủ đều biết để hmac băm một tin nhắn, nên sử dụng HMAC256. Hầu hết các trường hợp, mật khẩu băm của người tiêu dùng được sử dụng như một khóa bí mật.
Thông báo thường được xây dựng từ dữ liệu trong yêu cầu HTTP hoặc thậm chí dữ liệu tùy chỉnh được thêm vào tiêu đề HTTP, thông báo có thể bao gồm:
- Dấu thời gian: thời gian yêu cầu được gửi (UTC hoặc GMT)
- Động từ HTTP: GET, POST, PUT, DELETE.
- gửi dữ liệu và chuỗi truy vấn,
- URL
Dưới vỏ bọc, xác thực HMAC sẽ là:
Người tiêu dùng gửi yêu cầu HTTP đến máy chủ web, sau khi xây dựng chữ ký (đầu ra của hàm băm hmac), mẫu yêu cầu HTTP:
User-Agent: {agent}
Host: {host}
Timestamp: {timestamp}
Authentication: {username}:{signature}
Ví dụ cho yêu cầu GET:
GET /webapi.hmac/api/values
User-Agent: Fiddler
Host: localhost
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
Thông báo băm để lấy chữ ký:
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
Ví dụ cho yêu cầu POST với chuỗi truy vấn (chữ ký bên dưới không chính xác, chỉ là một ví dụ)
POST /webapi.hmac/api/values?key2=value2
User-Agent: Fiddler
Host: localhost
Content-Type: application/x-www-form-urlencoded
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
key1=value1&key3=value3
Thông báo băm để có được chữ ký
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
key1=value1&key2=value2&key3=value3
Xin lưu ý rằng dữ liệu biểu mẫu và chuỗi truy vấn phải theo thứ tự, vì vậy mã trên máy chủ nhận chuỗi truy vấn và dữ liệu biểu mẫu để tạo thông báo chính xác.
Khi yêu cầu HTTP đến máy chủ, bộ lọc hành động xác thực được triển khai để phân tích yêu cầu để lấy thông tin: Động từ HTTP, dấu thời gian, uri, dữ liệu biểu mẫu và chuỗi truy vấn, sau đó dựa trên những điều này để xây dựng chữ ký (sử dụng hàm băm hmac) với bí mật khóa (mật khẩu băm) trên máy chủ.
Khóa bí mật được lấy từ cơ sở dữ liệu với tên người dùng theo yêu cầu.
Sau đó, mã máy chủ so sánh chữ ký theo yêu cầu với chữ ký được xây dựng; nếu bằng nhau, xác thực được thông qua, nếu không, nó đã thất bại.
Mã để xây dựng chữ ký:
private static string ComputeHash(string hashedPassword, string message)
{
var key = Encoding.UTF8.GetBytes(hashedPassword.ToUpper());
string hashString;
using (var hmac = new HMACSHA256(key))
{
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
hashString = Convert.ToBase64String(hash);
}
return hashString;
}
Vậy, làm thế nào để ngăn chặn tấn công lại?
Thêm ràng buộc cho dấu thời gian, đại loại như:
servertime - X minutes|seconds <= timestamp <= servertime + X minutes|seconds
(servertime: thời gian yêu cầu đến máy chủ)
Và, lưu trữ chữ ký của yêu cầu trong bộ nhớ (sử dụng MemoryCache, nên giữ trong giới hạn thời gian). Nếu yêu cầu tiếp theo đi kèm cùng chữ ký với yêu cầu trước đó, nó sẽ bị từ chối.
Mã trình diễn được đặt ở đây:
https://github.com/cuongle/Hmac.WebApi