Kode otentikasi pesan berbasis hash (HMAC) adalah mekanisme untuk menghitung kode otentikasi pesan yang melibatkan fungsi hash yang dikombinasikan dengan kunci rahasia. Ini dapat digunakan untuk memverifikasi integritas dan keaslian pesan.
Implementasi ini sangat terinspirasi oleh metode otentikasi utama yang digunakan oleh Amazon Web Services (AWS Signature V4) karena sangat dipahami, dan ada sejumlah perpustakaan yang menerapkannya. Untuk menggunakan bentuk autentikasi ini, Anda menggunakan pengidentifikasi kunci dan kunci rahasia, yang keduanya biasanya dihasilkan di antarmuka admin.
HmacAuthentication menyediakan AuthenticationHandler
yang mendukung otentikasi HMAC dalam proyek ASP.NET Core.
Penggunaan:
appsettings.json
. Untuk autentikasi HMAC, AppId
dan ApiKey
diperlukan untuk setiap klien yang harus mendapatkan akses. 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
dalam metode ConfigureServices
: services
. AddAuthentication ( o =>
{
o . DefaultScheme = HmacAuthenticationDefaults . AuthenticationScheme ;
} )
. AddHmacAuthentication ( HmacAuthenticationDefaults . AuthenticationScheme , " HMAC Authentication " , o =>
{
o . MaxRequestAgeInSeconds = HmacAuthenticationDefaults . MaxRequestAgeInSeconds ;
o . HmacAuthenticatedApps = hmacAuthenticatedApps ;
} ) ;
MemoryCache
(dari Microsoft.Extensions.Caching.Memory) di Startup.cs
dalam metode ConfigureServices
. MemoryCache
digunakan oleh HMAC AuthenticationHandler
untuk menentukan serangan replay. services . AddMemoryCache ( ) ;
Startup.cs
dalam metode Configure
: app . UseAuthentication ( ) ;
[ Authorize ( AuthenticationSchemes = HmacAuthenticationDefaults . AuthenticationScheme ) ]
[ Route ( " api/[controller] " ) ]
public class HomeController : Controller
{
// ...
}
HmacAuthenticaion juga menyediakan DelegatingHandler
untuk menambahkan header otorisasi HMAC ke permintaan HTTP.
Buat instance HttpClient
Anda dengan ApiKeyDelegatingHandler
. Pastikan Anda tidak membuat instance HttpClient
baru untuk setiap permintaan (lihat juga postingan blog ini untuk detailnya):
new HttpClient ( new ApiKeyDelegatingHandler ( appId , apiKey ) ) ;
Atau jika klien WebAPI Anda adalah ASP.NET WebAPI lain (>= ASP.NET Core 2.1), daftarkan HttpClient
Anda di Startup.cs
misalnya sebagai berikut:
services . AddTransient ( sp => new ApiKeyDelegatingHandler ( appId , apiKey ) ) ;
services
. AddHttpClient ( " HmacHttpClient " )
. AddHttpMessageHandler < ApiKeyDelegatingHandler > ( ) ;
Untuk menghasilkan Kunci API, Aplikasi Konsol sederhana berikut dapat digunakan. Implementasi ini juga disediakan di .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 ) ;
}
}
}
Sumber risiko keamanan terbesar biasanya tidak ditemukan pada Protokol Auth namun pada kebijakan dan prosedur seputar penggunaannya. Para pelaksana sangat dianjurkan untuk menilai bagaimana modul ini memenuhi persyaratan keamanan mereka. Bagian ini mencakup daftar lengkap pertimbangan keamanan yang harus ditinjau dan dipahami sebelum menerapkan protokol Auth ini di server. Banyak perlindungan yang diberikan dalam spesifikasi bergantung pada apakah dan bagaimana perlindungan tersebut digunakan.
HmacAuthentication tidak menyediakan mekanisme apa pun untuk memperoleh atau mengirimkan kumpulan kredensial bersama yang diperlukan. Mekanisme apa pun yang digunakan untuk mendapatkan kredensial HmacAuthentication harus memastikan bahwa transmisi ini dilindungi menggunakan mekanisme lapisan transport seperti TLS.
Meskipun HmacAuthentication menyediakan mekanisme untuk memverifikasi integritas permintaan HTTP, HmacAuthentication tidak memberikan jaminan kerahasiaan permintaan. Kecuali tindakan pencegahan lain dilakukan, penyadap akan memiliki akses penuh ke konten permintaan. Server harus hati-hati mempertimbangkan jenis data yang mungkin dikirim sebagai bagian dari permintaan tersebut, dan menggunakan mekanisme keamanan lapisan transport untuk melindungi sumber daya sensitif.
HmacAuthentication menyediakan verifikasi terbatas terhadap keaslian server. Saat menerima respon balik dari server.
Pihak yang bermusuhan dapat mengambil keuntungan dari hal ini dengan menghalangi permintaan klien dan memberikan tanggapan yang menyesatkan atau salah. Penyedia layanan harus mempertimbangkan serangan tersebut ketika mengembangkan layanan menggunakan protokol ini, dan harus memerlukan keamanan lapisan transport untuk setiap permintaan yang keaslian server sumber daya atau respons server menjadi masalah.
Kunci HmacAuthentication berfungsi sama seperti kata sandi pada sistem autentikasi tradisional. Untuk menghitung permintaan MAC, server harus memiliki akses ke kunci dalam bentuk teks biasa. Hal ini berbeda, misalnya, dengan sistem operasi modern, yang hanya menyimpan hash kredensial pengguna satu arah.
Jika penyerang mendapatkan akses ke kunci-kunci ini - atau lebih buruk lagi, ke database server yang berisi semua kunci tersebut - dia akan dapat melakukan tindakan apa pun atas nama pemilik sumber daya mana pun. Oleh karena itu, sangat penting bagi server untuk melindungi kunci-kunci ini dari akses yang tidak sah.
Kecuali jika protokol keamanan lapisan transport digunakan, penyadap akan memiliki akses penuh terhadap permintaan yang diautentikasi dan meminta nilai MAC, dan dengan demikian akan dapat melakukan serangan brute force offline untuk memulihkan kunci yang digunakan. Server harus berhati-hati dalam menetapkan kunci yang cukup panjang, dan cukup acak, untuk menahan serangan tersebut setidaknya selama kredensial HmacAuthentication valid.
Misalnya, jika kredensial valid selama dua minggu, server harus memastikan bahwa tidak mungkin melakukan serangan brute force yang memulihkan kunci dalam waktu kurang dari dua minggu. Tentu saja, server dihimbau untuk berhati-hati dan menggunakan kunci terpanjang secara wajar.
Hal yang sama pentingnya adalah generator bilangan acak semu (PRNG) yang digunakan untuk menghasilkan kunci-kunci ini memiliki kualitas yang cukup tinggi. Banyak implementasi PRNG menghasilkan urutan angka yang mungkin tampak acak, namun tetap menunjukkan pola atau kelemahan lain yang membuat serangan kriptanalisis atau brute force lebih mudah. Pelaksana harus berhati-hati dalam menggunakan PRNG yang aman secara kriptografis untuk menghindari masalah ini.
Permintaan MAC hanya mencakup header HTTP Host
, header Content-Type
, dan secara opsional serangkaian Header tertentu. Itu tidak mencakup header lain yang tidak diketahuinya yang seringkali dapat mempengaruhi bagaimana isi permintaan ditafsirkan oleh server. Jika perilaku server dipengaruhi oleh keberadaan atau nilai header tersebut, penyerang dapat memanipulasi header permintaan tanpa terdeteksi. Pelaksana harus menggunakan fitur headers
untuk meneruskan header untuk ditambahkan ke tanda tangan melalui header Authorization
yang dilindungi oleh permintaan MAC. Signature Base String kemudian akan bertanggung jawab untuk menambahkan header yang diberikan ini ke Signature sehingga menjadi bagian dari MAC.
Otentikasi respons, ketika dilakukan, hanya mencakup Isi respons (payload) dan beberapa informasi permintaan yang disediakan oleh klien dalam permintaannya seperti stempel waktu dan nonce. Ini tidak mencakup kode status HTTP atau bidang header respons lainnya (misalnya Lokasi) yang dapat mempengaruhi perilaku klien.
Jika penyerang mampu memanipulasi informasi ini dan menyebabkan klien menggunakan waktu yang salah, hal ini dapat menyebabkan klien menghasilkan permintaan terotentikasi menggunakan waktu di masa mendatang. Permintaan tersebut akan gagal ketika dikirim oleh klien, dan kemungkinan besar tidak akan meninggalkan jejak di server (mengingat penerapan nonce yang umum, jika diterapkan). Penyerang kemudian dapat memutar ulang permintaan tersebut pada waktu yang tepat tanpa terdeteksi.
Solusi untuk masalah ini adalah sinkronisasi jam antara klien dan server. Untuk mencapai hal ini, server memberi tahu klien tentang waktu saat ini ketika stempel waktu yang tidak valid diterima. Ini terjadi dalam bentuk header Tanggal di respons. Lihat RFC2616 sebagai motivasi untuk ini.
Klien hanya boleh menggunakan informasi waktu yang disediakan oleh server jika:
Saat menerima permintaan dengan stempel waktu yang buruk, server memberikan waktu saat ini kepada klien. Klien tidak boleh menggunakan waktu yang diterima dari server untuk mengatur jamnya sendiri, dan hanya boleh menggunakannya untuk menghitung offset untuk berkomunikasi dengan server tersebut.
HmacAuthentication memvalidasi permintaan MAC yang masuk terhadap header HTTP Host yang masuk. Klien jahat dapat membuat nama host baru yang menunjuk ke alamat IP server dan menggunakannya untuk membuat serangan dengan mengirimkan permintaan valid yang dimaksudkan untuk nama host lain selain yang digunakan oleh server. Pelaksana server harus memverifikasi secara manual bahwa header host yang diterima sesuai dengan harapan mereka. Misalnya, jika Anda mengharapkan panggilan API di test.myapi.com, verifikasi bahwa itu adalah domain tujuan pengiriman permintaan dalam implementasi server.