Mise à jour:
J'ai ajouté ce lien à mon autre réponse comment utiliser l'authentification JWT pour l'API Web ASP.NET ici pour toute personne intéressée par JWT.
Nous avons réussi à appliquer l'authentification HMAC à l'API Web sécurisée, et cela a bien fonctionné. L'authentification HMAC utilise une clé secrète pour chaque consommateur que le consommateur et le serveur connaissent tous les deux pour hmac hacher un message, HMAC256 doit être utilisé. La plupart des cas, le mot de passe haché du consommateur est utilisé comme clé secrète.
Le message est normalement construit à partir des données de la requête HTTP, ou même des données personnalisées qui sont ajoutées à l'en-tête HTTP, le message peut inclure:
- Horodatage: heure à laquelle la demande est envoyée (UTC ou GMT)
- Verbe HTTP: GET, POST, PUT, DELETE.
- publier des données et une chaîne de requête,
- URL
Sous le capot, l'authentification HMAC serait:
Le consommateur envoie une requête HTTP au serveur web, après avoir construit la signature (sortie du hachage hmac), le modèle de requête HTTP:
User-Agent: {agent}
Host: {host}
Timestamp: {timestamp}
Authentication: {username}:{signature}
Exemple de demande GET:
GET /webapi.hmac/api/values
User-Agent: Fiddler
Host: localhost
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
Le message à hacher pour obtenir la signature:
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
Exemple de demande POST avec chaîne de requête (la signature ci-dessous n'est pas correcte, juste un exemple)
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
Le message à hacher pour obtenir la signature
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
key1=value1&key2=value2&key3=value3
Veuillez noter que les données de formulaire et la chaîne de requête doivent être en ordre, de sorte que le code sur le serveur récupère la chaîne de requête et les données de formulaire pour générer le message correct.
Lorsque la demande HTTP arrive sur le serveur, un filtre d'action d'authentification est implémenté pour analyser la demande afin d'obtenir des informations: verbe HTTP, horodatage, uri, données de formulaire et chaîne de requête, puis basé sur ceux-ci pour créer une signature (utiliser le hachage hmac) avec le secret clé (mot de passe haché) sur le serveur.
La clé secrète est obtenue de la base de données avec le nom d'utilisateur sur la demande.
Ensuite, le code serveur compare la signature de la demande avec la signature créée; si égal, l'authentification est passée, sinon, elle a échoué.
Le code pour construire la signature:
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;
}
Alors, comment empêcher l'attaque de rejeu?
Ajoutez une contrainte pour l'horodatage, quelque chose comme:
servertime - X minutes|seconds <= timestamp <= servertime + X minutes|seconds
(heure du serveur: heure de la demande qui arrive au serveur)
Et, mettez en cache la signature de la requête en mémoire (utilisez MemoryCache, devrait rester dans la limite de temps). Si la prochaine demande est accompagnée de la même signature que la précédente, elle sera rejetée.
Le code de démonstration est mis comme ici:
https://github.com/cuongle/Hmac.WebApi