Le code d'authentification de message basé sur le hachage (HMAC) est un mécanisme permettant de calculer un code d'authentification de message impliquant une fonction de hachage en combinaison avec une clé secrète. Cela peut être utilisé pour vérifier l’intégrité et l’authenticité d’un message.
Cette implémentation s'inspire fortement de la principale méthode d'authentification utilisée par Amazon Web Services (AWS Signature V4) car elle est très bien comprise, et il existe un certain nombre de bibliothèques qui l'implémentent. Pour utiliser cette forme d'authentification, vous utilisez un identifiant de clé et une clé secrète, les deux étant généralement générés dans une interface d'administration.
HmacAuthentication fournit un AuthenticationHandler
qui prend en charge l'authentification HMAC dans un projet ASP.NET Core.
Usage:
appsettings.json
. Pour l'authentification HMAC, un AppId
et une ApiKey
sont requis pour chaque client qui doit avoir accès. 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
dans la méthode ConfigureServices
: services
. AddAuthentication ( o =>
{
o . DefaultScheme = HmacAuthenticationDefaults . AuthenticationScheme ;
} )
. AddHmacAuthentication ( HmacAuthenticationDefaults . AuthenticationScheme , " HMAC Authentication " , o =>
{
o . MaxRequestAgeInSeconds = HmacAuthenticationDefaults . MaxRequestAgeInSeconds ;
o . HmacAuthenticatedApps = hmacAuthenticatedApps ;
} ) ;
MemoryCache
(à partir de Microsoft.Extensions.Caching.Memory) dans Startup.cs
dans la méthode ConfigureServices
. Le MemoryCache
est utilisé par le HMAC AuthenticationHandler
pour déterminer les attaques par réexécution. services . AddMemoryCache ( ) ;
Startup.cs
dans la méthode Configure
: app . UseAuthentication ( ) ;
[ Authorize ( AuthenticationSchemes = HmacAuthenticationDefaults . AuthenticationScheme ) ]
[ Route ( " api/[controller] " ) ]
public class HomeController : Controller
{
// ...
}
HmacAuthenticaion fournit également un DelegatingHandler
pour ajouter un en-tête d'autorisation HMAC aux requêtes HTTP.
Instanciez votre instance HttpClient
avec ApiKeyDelegatingHandler
. Assurez-vous de ne pas créer de nouvelles instances HttpClient
pour chaque requête (voir également cet article de blog pour plus de détails) :
new HttpClient ( new ApiKeyDelegatingHandler ( appId , apiKey ) ) ;
Ou si votre client WebAPI est une autre WebAPI ASP.NET (>= ASP.NET Core 2.1), enregistrez votre HttpClient
dans Startup.cs
par exemple comme suit :
services . AddTransient ( sp => new ApiKeyDelegatingHandler ( appId , apiKey ) ) ;
services
. AddHttpClient ( " HmacHttpClient " )
. AddHttpMessageHandler < ApiKeyDelegatingHandler > ( ) ;
Pour générer une clé API, l'application console simple suivante peut être utilisée. Cette implémentation est également fournie sur .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 ) ;
}
}
}
Les plus grandes sources de risques de sécurité ne se trouvent généralement pas dans le protocole d’authentification mais dans les politiques et procédures entourant son utilisation. Les responsables de la mise en œuvre sont fortement encouragés à évaluer la manière dont ce module répond à leurs exigences de sécurité. Cette section comprend une liste incomplète de considérations de sécurité qui doivent être examinées et comprises avant de déployer ce protocole d'authentification sur le serveur. La plupart des protections fournies dans les spécifications dépendent de leur utilisation et de la manière dont elles sont utilisées.
HmacAuthentication ne fournit aucun mécanisme pour obtenir ou transmettre l'ensemble d'informations d'identification partagées requis. Tout mécanisme utilisé pour obtenir les informations d'identification HmacAuthentication doit garantir que ces transmissions sont protégées à l'aide de mécanismes de couche transport tels que TLS.
Bien que HmacAuthentication fournisse un mécanisme permettant de vérifier l'intégrité des requêtes HTTP, il ne fournit aucune garantie de confidentialité des requêtes. À moins que d’autres précautions ne soient prises, les oreilles indiscrètes auront un accès complet au contenu de la demande. Les serveurs doivent examiner attentivement les types de données susceptibles d'être envoyés dans le cadre de telles requêtes et utiliser des mécanismes de sécurité au niveau de la couche transport pour protéger les ressources sensibles.
HmacAuthentication fournit une vérification limitée de l'authenticité du serveur. Lors de la réception d'une réponse du serveur.
Une partie hostile pourrait en profiter en interceptant les demandes du client et en renvoyant des réponses trompeuses ou incorrectes. Les fournisseurs de services devraient prendre en compte de telles attaques lors du développement de services utilisant ce protocole et devraient exiger une sécurité au niveau de la couche transport pour toute demande où l'authenticité du serveur de ressources ou des réponses du serveur pose problème.
La clé HmacAuthentication fonctionne de la même manière que les mots de passe dans les systèmes d'authentification traditionnels. Afin de calculer la requête MAC, le serveur doit avoir accès à la clé sous forme de texte en clair. Cela contraste, par exemple, avec les systèmes d'exploitation modernes, qui stockent uniquement un hachage unidirectionnel des informations d'identification des utilisateurs.
Si un attaquant parvenait à accéder à ces clés - ou pire, à la base de données du serveur contenant toutes ces clés - il pourrait effectuer n'importe quelle action au nom de n'importe quel propriétaire de ressource. Par conséquent, il est essentiel que les serveurs protègent ces clés contre tout accès non autorisé.
À moins qu'un protocole de sécurité de couche transport ne soit utilisé, les oreilles indiscrètes auront un accès complet aux requêtes authentifiées et aux valeurs MAC des requêtes, et pourront ainsi lancer des attaques par force brute hors ligne pour récupérer la clé utilisée. Les serveurs doivent veiller à attribuer des clés suffisamment longues et suffisamment aléatoires pour résister à de telles attaques pendant au moins la durée pendant laquelle les informations d'identification HmacAuthentication sont valides.
Par exemple, si les informations d’identification sont valides pendant deux semaines, les serveurs doivent s’assurer qu’il n’est pas possible de lancer une attaque par force brute permettant de récupérer la clé en moins de deux semaines. Bien entendu, les serveurs sont invités à faire preuve de prudence et à utiliser la clé la plus longue raisonnablement.
Il est également important que le générateur de nombres pseudo-aléatoires (PRNG) utilisé pour générer ces clés soit de qualité suffisamment élevée. De nombreuses implémentations de PRNG génèrent des séquences de nombres qui peuvent sembler aléatoires, mais qui présentent néanmoins des modèles ou d'autres faiblesses qui facilitent la cryptanalyse ou les attaques par force brute. Les développeurs doivent veiller à utiliser des PRNG cryptographiquement sécurisés pour éviter ces problèmes.
La requête MAC couvre uniquement l'en-tête HTTP Host
, l'en-tête Content-Type
et éventuellement un ensemble donné d'en-têtes. Il ne couvre pas les autres en-têtes dont il ne connaît pas l'existence et qui peuvent souvent affecter la façon dont le corps de la requête est interprété par le serveur. Si le comportement du serveur est influencé par la présence ou la valeur de tels en-têtes, un attaquant peut manipuler les en-têtes de requête sans être détecté. Les implémenteurs doivent utiliser la fonctionnalité headers
pour transmettre les en-têtes à ajouter à la signature via l'en-tête Authorization
qui est protégé par le MAC de la requête. La chaîne de base de signature sera ensuite chargée d'ajouter ces en-têtes donnés à la signature afin qu'ils fassent partie du MAC.
L'authentification de la réponse, lorsqu'elle est effectuée, couvre uniquement le corps de la réponse (charge utile) et certaines des informations de demande fournies par le client dans sa demande, telles que l'horodatage et le nom occasionnel. Il ne couvre pas le code d'état HTTP ou tout autre champ d'en-tête de réponse (par exemple Emplacement) qui peut affecter le comportement du client.
Si un attaquant est capable de manipuler ces informations et d'amener le client à utiliser une heure incorrecte, il pourrait amener le client à générer des requêtes authentifiées en utilisant l'heure à l'avenir. De telles requêtes échoueront lorsqu'elles seront envoyées par le client et ne laisseront probablement pas de trace sur le serveur (étant donné l'implémentation courante du nonce, voire pas du tout appliqué). L’attaquant pourra alors rejouer la requête au bon moment sans détection.
Une solution à ce problème serait une synchronisation d'horloge entre le client et le serveur. Pour ce faire, le serveur informe le client de son heure actuelle lorsqu'un horodatage non valide est reçu. Cela se produit sous la forme d’un en-tête Date dans la réponse. Voir la RFC2616 comme motivation pour cela.
Le client ne doit utiliser les informations horaires fournies par le serveur que si :
Lors de la réception d'une requête avec un mauvais horodatage, le serveur fournit au client son heure actuelle. Le client ne doit jamais utiliser l'heure reçue du serveur pour régler sa propre horloge et doit uniquement l'utiliser pour calculer un décalage pour communiquer avec ce serveur particulier.
HmacAuthentication valide la requête MAC entrante par rapport à l'en-tête de l'hôte HTTP entrant. Un client malveillant peut créer de nouveaux noms d'hôte pointant vers l'adresse IP du serveur et l'utiliser pour lancer une attaque en envoyant une requête valide destinée à un autre nom d'hôte que celui utilisé par le serveur. Les implémenteurs de serveur doivent vérifier manuellement que l'en-tête d'hôte reçu correspond à leurs attentes. Par exemple, si vous attendez des appels API sur test.myapi.com, vérifiez qu'il s'agit du domaine auquel la requête a été envoyée dans l'implémentation du serveur.