ปรับปรุง:
ฉันได้เพิ่มลิงค์นี้ไปยังคำตอบอื่น ๆ ของฉันวิธีการใช้การพิสูจน์ตัวตน JWT สำหรับ ASP.NET Web APIที่นี่สำหรับทุกคนที่สนใจ JWT
เรามีการจัดการเพื่อใช้การรับรองความถูกต้อง HMAC เพื่อรักษาความปลอดภัยเว็บ API และมันก็ใช้ได้ การพิสูจน์ตัวตน HMAC ใช้คีย์ลับสำหรับผู้ใช้แต่ละรายซึ่งทั้งผู้บริโภคและเซิร์ฟเวอร์รู้ว่าจะ hmac แฮชข้อความควรใช้ HMAC256 ส่วนใหญ่แล้วรหัสผ่านที่ถูกแฮชของผู้ใช้บริการจะถูกใช้เป็นรหัสลับ
โดยปกติข้อความจะถูกสร้างขึ้นจากข้อมูลในคำขอ HTTP หรือแม้แต่ข้อมูลที่กำหนดเองซึ่งถูกเพิ่มไปยังส่วนหัว HTTP ข้อความอาจรวมถึง:
- Timestamp: เวลาที่ส่งคำขอ (UTC หรือ GMT)
- HTTP verb: GET, POST, PUT, DELETE
- โพสต์ข้อมูลและสตริงการสืบค้น
- URL
ภายใต้ประทุนการตรวจสอบ HMAC จะเป็น:
Consumer ส่งคำร้องขอ HTTP ไปยังเว็บเซิร์ฟเวอร์หลังจากสร้างลายเซ็น (เอาต์พุตของ hmac hash) เท็มเพลตของคำร้องขอ HTTP:
User-Agent: {agent}
Host: {host}
Timestamp: {timestamp}
Authentication: {username}:{signature}
ตัวอย่างสำหรับคำขอ GET:
GET /webapi.hmac/api/values
User-Agent: Fiddler
Host: localhost
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
ข้อความที่จะแฮชเพื่อรับลายเซ็น:
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
ตัวอย่างสำหรับคำขอ POST ที่มีสตริงข้อความค้นหา (ลายเซ็นด้านล่างไม่ถูกต้องเป็นเพียงตัวอย่าง)
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
ข้อความที่จะแฮชเพื่อรับลายเซ็น
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
key1=value1&key2=value2&key3=value3
โปรดทราบว่าข้อมูลฟอร์มและสตริงการสืบค้นควรเป็นไปตามลำดับดังนั้นโค้ดบนเซิร์ฟเวอร์จะได้รับสตริงการสืบค้นและข้อมูลฟอร์มเพื่อสร้างข้อความที่ถูกต้อง
เมื่อคำขอ HTTP มาถึงเซิร์ฟเวอร์ตัวกรองการดำเนินการตรวจสอบความถูกต้องจะดำเนินการเพื่อแยกวิเคราะห์คำขอเพื่อรับข้อมูล: กริยา HTTP, เวลาประทับ, uri ข้อมูลในฟอร์มและสตริงการสืบค้นจากนั้นยึดตามสิ่งเหล่านี้เพื่อสร้างลายเซ็น (ใช้ hmac hash) คีย์ (รหัสผ่านที่แฮช) บนเซิร์ฟเวอร์
รหัสลับนั้นได้มาจากฐานข้อมูลพร้อมชื่อผู้ใช้ในคำขอ
จากนั้นรหัสเซิร์ฟเวอร์จะเปรียบเทียบลายเซ็นต์ในคำขอกับลายเซ็นที่สร้างขึ้น หากเท่ากันจะผ่านการตรวจสอบความถูกต้องมิฉะนั้นจะล้มเหลว
รหัสเพื่อสร้างลายเซ็น:
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;
}
ดังนั้นวิธีป้องกันการโจมตีซ้ำ?
เพิ่มข้อ จำกัด สำหรับการประทับเวลาบางอย่างเช่น:
servertime - X minutes|seconds <= timestamp <= servertime + X minutes|seconds
(เวลา: เวลาของการร้องขอมาถึงเซิร์ฟเวอร์)
และแคชลายเซ็นของคำขอในหน่วยความจำ (ใช้ MemoryCache ควรเก็บในเวลาที่ จำกัด ) หากคำขอถัดไปมาพร้อมกับลายเซ็นเดียวกันกับคำขอก่อนหน้านี้คำขอนั้นจะถูกปฏิเสธ
รหัสตัวอย่างใส่ไว้ที่นี่:
https://github.com/cuongle/Hmac.WebApi