รหัสตรวจสอบข้อความแบบแฮช (HMAC) เป็นกลไกในการคำนวณรหัสตรวจสอบข้อความที่เกี่ยวข้องกับฟังก์ชันแฮชร่วมกับรหัสลับ ซึ่งสามารถใช้เพื่อตรวจสอบความสมบูรณ์และความถูกต้องของข้อความ aa
การใช้งานนี้ได้รับแรงบันดาลใจอย่างมากจากวิธีการตรวจสอบสิทธิ์หลักที่ใช้โดย Amazon Web Services (AWS Signature V4) เนื่องจากเป็นที่เข้าใจกันเป็นอย่างดี และมีไลบรารีจำนวนหนึ่งที่นำไปใช้ หากต้องการใช้รูปแบบการตรวจสอบสิทธิ์นี้ คุณต้องใช้ตัวระบุคีย์และคีย์ลับ ซึ่งโดยทั่วไปทั้งสองอย่างนี้จะสร้างในส่วนติดต่อผู้ดูแลระบบ
HmacAuthentication มี AuthenticationHandler
ซึ่งรองรับการตรวจสอบสิทธิ์ HMAC ในโครงการ ASP.NET Core
การใช้งาน:
appsettings.json
สำหรับการตรวจสอบสิทธิ์ HMAC จำเป็นต้องมี AppId
และ ApiKey
สำหรับไคลเอ็นต์แต่ละเครื่องที่ควรได้รับสิทธิ์เข้าถึง var hmacAuthenticatedApps = this . Configuration
. GetSection ( " Authentication " )
. GetSection ( " HmacAuthenticatedApps " )
. Get < HmacAuthenticationClientConfiguration [ ] > ( )
. ToDictionary ( e => e . AppId , e => e . ApiKey ) ;
{
"Authentication" : {
"HmacAuthenticatedApps" : [
{
"AppId" : " <some-app-id> " ,
"ApiKey" : " <some-api-key> "
}
]
}
}
Startup.cs
ในวิธี ConfigureServices
: services
. AddAuthentication ( o =>
{
o . DefaultScheme = HmacAuthenticationDefaults . AuthenticationScheme ;
} )
. AddHmacAuthentication ( HmacAuthenticationDefaults . AuthenticationScheme , " HMAC Authentication " , o =>
{
o . MaxRequestAgeInSeconds = HmacAuthenticationDefaults . MaxRequestAgeInSeconds ;
o . HmacAuthenticatedApps = hmacAuthenticatedApps ;
} ) ;
MemoryCache
(จาก Microsoft.Extensions.Caching.Memory) ใน Startup.cs
ในวิธี ConfigureServices
MemoryCache
ถูกใช้โดย HMAC AuthenticationHandler
เพื่อระบุการโจมตีแบบเล่นซ้ำ services . AddMemoryCache ( ) ;
Startup.cs
ในวิธี Configure
: app . UseAuthentication ( ) ;
[ Authorize ( AuthenticationSchemes = HmacAuthenticationDefaults . AuthenticationScheme ) ]
[ Route ( " api/[controller] " ) ]
public class HomeController : Controller
{
// ...
}
HmacAuthenticaion ยังมี DelegatingHandler
สำหรับการเพิ่มส่วนหัวการอนุญาต HMAC ไปยังคำขอ HTTP
สร้างอินสแตนซ์ HttpClient
ของคุณด้วย ApiKeyDelegatingHandler
ตรวจสอบให้แน่ใจว่าคุณไม่ได้สร้างอินสแตนซ์ HttpClient
ใหม่สำหรับทุกคำขอ (ดูรายละเอียดเพิ่มเติมในบล็อกโพสต์นี้):
new HttpClient ( new ApiKeyDelegatingHandler ( appId , apiKey ) ) ;
หรือในกรณีที่ไคลเอ็นต์ WebAPI ของคุณเป็น ASP.NET WebAPI อื่น (>= ASP.NET Core 2.1) ให้ลงทะเบียน HttpClient
ของคุณใน Startup.cs
ดังนี้:
services . AddTransient ( sp => new ApiKeyDelegatingHandler ( appId , apiKey ) ) ;
services
. AddHttpClient ( " HmacHttpClient " )
. AddHttpMessageHandler < ApiKeyDelegatingHandler > ( ) ;
ในการสร้างคีย์ API คุณสามารถใช้แอปพลิเคชันคอนโซลแบบง่ายต่อไปนี้ได้ การใช้งานนี้มีให้ใน .NET Fiddle ด้วย
using System . Security . Cryptography ;
public class Program
{
public static void Main ( )
{
Console . WriteLine ( $" AppID: { Guid . NewGuid ( ) } or <some-speaking-name> " ) ;
Console . WriteLine ( $" ApiKey: { GenerateApiKey ( ) } " ) ;
}
private static string GenerateApiKey ( )
{
using ( var cryptoProvider = new RNGCryptoServiceProvider ( ) )
{
byte [ ] secretKeyByteArray = new byte [ 32 ] ; //256 bit
cryptoProvider . GetBytes ( secretKeyByteArray ) ;
return Convert . ToBase64String ( secretKeyByteArray ) ;
}
}
}
แหล่งที่มาของความเสี่ยงด้านความปลอดภัยที่ยิ่งใหญ่ที่สุดมักไม่พบใน Auth Protocol แต่พบในนโยบายและขั้นตอนที่เกี่ยวข้องกับการใช้งาน ผู้ดำเนินการได้รับการสนับสนุนอย่างยิ่งให้ประเมินว่าโมดูลนี้ตอบสนองความต้องการด้านความปลอดภัยของตนอย่างไร ส่วนนี้ประกอบด้วยรายการข้อควรพิจารณาด้านความปลอดภัยที่ไม่สมบูรณ์ซึ่งต้องได้รับการตรวจสอบและทำความเข้าใจก่อนที่จะปรับใช้โปรโตคอลการรับรองความถูกต้องนี้บนเซิร์ฟเวอร์ การป้องกันหลายประการที่ระบุในข้อกำหนดจำเพาะขึ้นอยู่กับว่ามีการใช้หรือไม่และอย่างไร
HmacAuthentication ไม่มีกลไกในการรับหรือส่งชุดข้อมูลรับรองที่ใช้ร่วมกันที่จำเป็น กลไกใดๆ ที่ใช้ในการรับข้อมูลรับรอง HmacAuthentication ต้องแน่ใจว่าการส่งข้อมูลเหล่านี้ได้รับการป้องกันโดยใช้กลไกในชั้นการขนส่ง เช่น TLS
แม้ว่า HmacAuthentication จะมีกลไกในการตรวจสอบความสมบูรณ์ของคำขอ HTTP แต่ก็ไม่ได้รับประกันการรักษาความลับของคำขอ ผู้ดักฟังจะสามารถเข้าถึงเนื้อหาคำขอได้อย่างเต็มที่ เว้นแต่จะใช้มาตรการป้องกันอื่นใด เซิร์ฟเวอร์ควรพิจารณาอย่างรอบคอบถึงประเภทของข้อมูลที่น่าจะถูกส่งโดยเป็นส่วนหนึ่งของคำขอดังกล่าว และใช้กลไกการรักษาความปลอดภัยในชั้นการขนส่งเพื่อปกป้องทรัพยากรที่ละเอียดอ่อน
HmacAuthentication ให้การตรวจสอบความถูกต้องของเซิร์ฟเวอร์อย่างจำกัด เมื่อได้รับการตอบกลับจากเซิร์ฟเวอร์
ฝ่ายที่ไม่เป็นมิตรสามารถใช้ประโยชน์จากสิ่งนี้ได้โดยการสกัดกั้นคำขอของลูกค้าและส่งคืนคำตอบที่ทำให้เข้าใจผิดหรือไม่ถูกต้อง ผู้ให้บริการควรพิจารณาการโจมตีดังกล่าวเมื่อพัฒนาบริการโดยใช้โปรโตคอลนี้ และควรต้องมีการรักษาความปลอดภัยชั้นการขนส่งสำหรับคำขอใดๆ ที่มีปัญหาความถูกต้องของเซิร์ฟเวอร์ทรัพยากรหรือการตอบสนองของเซิร์ฟเวอร์
ปุ่ม HmacAuthentication ทำงานในลักษณะเดียวกับที่รหัสผ่านทำในระบบการตรวจสอบสิทธิ์แบบดั้งเดิม ในการคำนวณคำขอ MAC เซิร์ฟเวอร์จะต้องมีสิทธิ์เข้าถึงคีย์ในรูปแบบข้อความธรรมดา สิ่งนี้ตรงกันข้ามกับระบบปฏิบัติการสมัยใหม่ที่จัดเก็บเฉพาะแฮชข้อมูลรับรองผู้ใช้ทางเดียว
หากผู้โจมตีเข้าถึงคีย์เหล่านี้ - หรือแย่กว่านั้นคือไปยังฐานข้อมูลของเซิร์ฟเวอร์ของคีย์ดังกล่าวทั้งหมด - เขาหรือเธอจะสามารถดำเนินการใดๆ ในนามของเจ้าของทรัพยากรได้ ดังนั้นจึงจำเป็นอย่างยิ่งที่เซิร์ฟเวอร์จะต้องปกป้องคีย์เหล่านี้จากการเข้าถึงที่ไม่ได้รับอนุญาต
ผู้ดักฟังจะสามารถเข้าถึงคำขอที่ได้รับการตรวจสอบสิทธิ์และขอค่า MAC ได้อย่างเต็มที่ เว้นแต่จะใช้โปรโตคอลความปลอดภัยในชั้นการขนส่ง และจะสามารถติดตั้งการโจมตีแบบ brute-force แบบออฟไลน์เพื่อกู้คืนคีย์ที่ใช้ได้ เซิร์ฟเวอร์ควรระมัดระวังในการกำหนดคีย์ที่ยาวเพียงพอ และสุ่มเพียงพอ เพื่อต้านทานการโจมตีดังกล่าวเป็นระยะเวลาอย่างน้อยที่ข้อมูลรับรอง HmacAuthentication นั้นถูกต้อง
ตัวอย่างเช่น หากข้อมูลประจำตัวถูกต้องเป็นเวลาสองสัปดาห์ เซิร์ฟเวอร์ควรตรวจสอบให้แน่ใจว่าไม่สามารถติดตั้งการโจมตีแบบ bruteforce ที่จะกู้คืนคีย์ได้ภายในเวลาไม่ถึงสองสัปดาห์ แน่นอนว่าเซิร์ฟเวอร์ได้รับการกระตุ้นให้ทำผิดด้วยความระมัดระวัง และใช้คีย์ที่ยาวที่สุดตามสมควร
สิ่งสำคัญไม่แพ้กันคือตัวสร้างตัวเลขสุ่มหลอก (PRNG) ที่ใช้สร้างคีย์เหล่านี้จะต้องมีคุณภาพสูงเพียงพอ การใช้งาน PRNG จำนวนมากสร้างลำดับตัวเลขที่อาจดูเหมือนสุ่ม แต่ยังคงแสดงรูปแบบหรือจุดอ่อนอื่น ๆ ที่ทำให้การเข้ารหัสลับหรือการโจมตีแบบเดรัจฉานทำได้ง่ายขึ้น ผู้ดำเนินการควรระมัดระวังในการใช้ PRNG ที่ปลอดภัยด้วยการเข้ารหัสเพื่อหลีกเลี่ยงปัญหาเหล่านี้
MAC คำขอครอบคลุมเฉพาะส่วนหัว Host
HTTP, ส่วนหัว Content-Type
และชุดส่วนหัวที่กำหนดหรือไม่ก็ได้ ไม่ครอบคลุมส่วนหัวอื่นใดที่ไม่ทราบว่าส่วนหัวใดมักจะส่งผลต่อวิธีที่เซิร์ฟเวอร์ตีความเนื้อหาคำขอ หากพฤติกรรมของเซิร์ฟเวอร์ได้รับอิทธิพลจากการมีอยู่หรือค่าของส่วนหัวดังกล่าว ผู้โจมตีสามารถจัดการส่วนหัวของคำขอโดยไม่ถูกตรวจพบ ผู้ดำเนินการควรใช้คุณลักษณะ headers
เพื่อส่งส่วนหัวที่จะเพิ่มให้กับลายเซ็นผ่านส่วนหัว Authorization
ซึ่งได้รับการป้องกันโดย MAC คำขอ สตริงฐานลายเซ็นจะรับผิดชอบในการเพิ่มส่วนหัวที่กำหนดเหล่านี้ให้กับลายเซ็นเพื่อให้เป็นส่วนหนึ่งของ MAC
เมื่อดำเนินการการตรวจสอบสิทธิ์การตอบสนอง จะครอบคลุมเฉพาะเนื้อหาการตอบสนอง (เพย์โหลด) และข้อมูลคำขอบางส่วนที่ไคลเอ็นต์ให้ไว้ในคำขอ เช่น การประทับเวลาและ nonce ไม่ครอบคลุมถึงรหัสสถานะ HTTP หรือฟิลด์ส่วนหัวการตอบกลับอื่น ๆ (เช่น ตำแหน่ง) ซึ่งอาจส่งผลต่อพฤติกรรมของลูกค้า
หากผู้โจมตีสามารถจัดการข้อมูลนี้และทำให้ไคลเอนต์ใช้เวลาไม่ถูกต้อง ก็จะทำให้ไคลเอนต์สร้างคำขอการรับรองความถูกต้องโดยใช้เวลาในอนาคตได้ คำขอดังกล่าวจะล้มเหลวเมื่อไคลเอ็นต์ส่ง และไม่น่าจะทิ้งร่องรอยไว้บนเซิร์ฟเวอร์ (หากพิจารณาจากการใช้งานทั่วไปของ nonce หากบังคับใช้เลย) ผู้โจมตีจะสามารถเล่นคำขอซ้ำในเวลาที่ถูกต้องโดยไม่ต้องตรวจพบ
วิธีแก้ไขปัญหานี้คือการซิงค์นาฬิการะหว่างไคลเอนต์และเซิร์ฟเวอร์ เพื่อให้บรรลุผลนี้ เซิร์ฟเวอร์จะแจ้งให้ไคลเอ็นต์ทราบเวลาปัจจุบันเมื่อได้รับการประทับเวลาที่ไม่ถูกต้อง สิ่งนี้เกิดขึ้นในรูปแบบของส่วนหัว Date ในการตอบกลับ ดู RFC2616 เป็นแรงจูงใจในเรื่องนี้
ลูกค้าควรใช้ข้อมูลเวลาที่เซิร์ฟเวอร์ให้มาเท่านั้นหาก:
เมื่อได้รับคำขอที่มีการประทับเวลาที่ไม่ถูกต้อง เซิร์ฟเวอร์จะแจ้งเวลาปัจจุบันให้กับลูกค้า ลูกค้าจะต้องไม่ใช้เวลาที่ได้รับจากเซิร์ฟเวอร์เพื่อปรับนาฬิกาของตนเอง และต้องใช้เพื่อคำนวณค่าชดเชยสำหรับการสื่อสารกับเซิร์ฟเวอร์นั้นเท่านั้น
HmacAuthentication ตรวจสอบความถูกต้องของคำขอ MAC ขาเข้ากับส่วนหัวของโฮสต์ HTTP ขาเข้า ไคลเอนต์ที่เป็นอันตรายสามารถสร้างชื่อโฮสต์ใหม่ที่ชี้ไปยังที่อยู่ IP ของเซิร์ฟเวอร์ และใช้สิ่งนั้นเพื่อสร้างการโจมตีโดยการส่งคำขอที่ถูกต้องซึ่งมีไว้สำหรับชื่อโฮสต์อื่นที่ไม่ใช่ชื่อที่เซิร์ฟเวอร์ใช้ ผู้ดำเนินการเซิร์ฟเวอร์ต้องตรวจสอบด้วยตนเองว่าส่วนหัวของโฮสต์ที่ได้รับตรงกับความคาดหวังของตน เช่น หากคุณคาดว่าจะมีการเรียก API บน test.myapi.com ให้ตรวจสอบว่านั่นคือโดเมนที่คำขอถูกส่งไปในการใช้งานเซิร์ฟเวอร์