El código de autenticación de mensajes basado en hash (HMAC) es un mecanismo para calcular un código de autenticación de mensajes que involucra una función hash en combinación con una clave secreta. Esto se puede utilizar para verificar la integridad y autenticidad de un mensaje.
Esta implementación está muy inspirada en el método de autenticación principal utilizado por Amazon Web Services (AWS Signature V4), como se entiende muy bien, y existen varias bibliotecas que lo implementan. Para utilizar esta forma de autenticación, utiliza un identificador de clave y una clave secreta, y ambas generalmente se generan en una interfaz de administración.
HmacAuthentication proporciona un AuthenticationHandler
que admite la autenticación HMAC en un proyecto ASP.NET Core.
Uso:
appsettings.json
. Para la autenticación HMAC, se requiere un AppId
y una ApiKey
para cada cliente que debe obtener acceso. 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
en el método ConfigureServices
: services
. AddAuthentication ( o =>
{
o . DefaultScheme = HmacAuthenticationDefaults . AuthenticationScheme ;
} )
. AddHmacAuthentication ( HmacAuthenticationDefaults . AuthenticationScheme , " HMAC Authentication " , o =>
{
o . MaxRequestAgeInSeconds = HmacAuthenticationDefaults . MaxRequestAgeInSeconds ;
o . HmacAuthenticatedApps = hmacAuthenticatedApps ;
} ) ;
MemoryCache
(de Microsoft.Extensions.Caching.Memory) en Startup.cs
en el método ConfigureServices
. HMAC AuthenticationHandler
utiliza MemoryCache
para determinar los ataques de repetición. services . AddMemoryCache ( ) ;
Startup.cs
en el método Configure
: app . UseAuthentication ( ) ;
[ Authorize ( AuthenticationSchemes = HmacAuthenticationDefaults . AuthenticationScheme ) ]
[ Route ( " api/[controller] " ) ]
public class HomeController : Controller
{
// ...
}
HmacAuthenticaion también proporciona un DelegatingHandler
para agregar un encabezado de autorización HMAC a las solicitudes HTTP.
Cree una instancia HttpClient
con ApiKeyDelegatingHandler
. Asegúrese de no crear nuevas instancias HttpClient
para cada solicitud (consulte también esta publicación de blog para obtener más detalles):
new HttpClient ( new ApiKeyDelegatingHandler ( appId , apiKey ) ) ;
O en caso de que su cliente WebAPI sea otro WebAPI ASP.NET (>= ASP.NET Core 2.1), registre su HttpClient
en Startup.cs
, por ejemplo, de la siguiente manera:
services . AddTransient ( sp => new ApiKeyDelegatingHandler ( appId , apiKey ) ) ;
services
. AddHttpClient ( " HmacHttpClient " )
. AddHttpMessageHandler < ApiKeyDelegatingHandler > ( ) ;
Para generar una clave API, se puede utilizar la siguiente aplicación de consola sencilla. Esta implementación también se proporciona en .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 ) ;
}
}
}
Las mayores fuentes de riesgos de seguridad generalmente no se encuentran en el protocolo de autenticación sino en las políticas y procedimientos que rodean su uso. Se recomienda encarecidamente a los implementadores que evalúen cómo este módulo aborda sus requisitos de seguridad. Esta sección incluye una lista incompleta de consideraciones de seguridad que deben revisarse y comprenderse antes de implementar este protocolo de autenticación en el servidor. Muchas de las protecciones proporcionadas en las especificaciones dependen de si se utilizan y cómo.
HmacAuthentication no proporciona ningún mecanismo para obtener o transmitir el conjunto de credenciales compartidas necesarias. Cualquier mecanismo utilizado para obtener credenciales de HmacAuthentication debe garantizar que estas transmisiones estén protegidas mediante mecanismos de capa de transporte como TLS.
Si bien HmacAuthentication proporciona un mecanismo para verificar la integridad de las solicitudes HTTP, no ofrece garantía de confidencialidad de las solicitudes. A menos que se tomen otras precauciones, los espías tendrán acceso completo al contenido de la solicitud. Los servidores deben considerar cuidadosamente los tipos de datos que probablemente se enviarán como parte de dichas solicitudes y emplear mecanismos de seguridad de la capa de transporte para proteger los recursos confidenciales.
HmacAuthentication proporciona una verificación limitada de la autenticidad del servidor. Al recibir una respuesta del servidor.
Una parte hostil podría aprovechar esto interceptando las solicitudes del cliente y devolviendo respuestas engañosas o incorrectas. Los proveedores de servicios deben considerar estos ataques al desarrollar servicios utilizando este protocolo y deben exigir seguridad en la capa de transporte para cualquier solicitud en la que la autenticidad del servidor de recursos o de las respuestas del servidor sea un problema.
La clave HmacAuthentication funciona de la misma manera que las contraseñas en los sistemas de autenticación tradicionales. Para calcular la MAC de solicitud, el servidor debe tener acceso a la clave en formato de texto sin formato. Esto contrasta, por ejemplo, con los sistemas operativos modernos, que almacenan sólo un hash unidireccional de las credenciales de usuario.
Si un atacante obtuviera acceso a estas claves, o peor aún, a la base de datos del servidor con todas esas claves, podría realizar cualquier acción en nombre de cualquier propietario de recurso. En consecuencia, es fundamental que los servidores protejan estas claves del acceso no autorizado.
A menos que se utilice un protocolo de seguridad de la capa de transporte, los espías tendrán acceso completo a las solicitudes autenticadas y solicitarán valores MAC y, por lo tanto, podrán montar ataques de fuerza bruta fuera de línea para recuperar la clave utilizada. Los servidores deben tener cuidado de asignar claves que sean lo suficientemente largas y aleatorias para resistir dichos ataques durante al menos el tiempo que las credenciales de HmacAuthentication sean válidas.
Por ejemplo, si las credenciales son válidas durante dos semanas, los servidores deben garantizar que no sea posible montar un ataque de fuerza bruta que recupere la clave en menos de dos semanas. Por supuesto, se insta a los servidores a ser cautelosos y utilizar la clave más larga que sea razonable.
Es igualmente importante que el generador de números pseudoaleatorios (PRNG) utilizado para generar estas claves sea de una calidad suficientemente alta. Muchas implementaciones de PRNG generan secuencias numéricas que pueden parecer aleatorias, pero que, sin embargo, exhiben patrones u otras debilidades que facilitan el criptoanálisis o los ataques de fuerza bruta. Los implementadores deben tener cuidado al utilizar PRNG criptográficamente seguros para evitar estos problemas.
La MAC de solicitud solo cubre el encabezado Host
HTTP, el encabezado Content-Type
y, opcionalmente, un conjunto determinado de encabezados. No cubre ningún otro encabezado que no conozca y que a menudo puede afectar la forma en que el servidor interpreta el cuerpo de la solicitud. Si el comportamiento del servidor se ve influenciado por la presencia o el valor de dichos encabezados, un atacante puede manipular los encabezados de solicitud sin ser detectado. Los implementadores deben usar la función headers
para pasar los encabezados que se agregarán a la firma a través del encabezado Authorization
que está protegido por la MAC de solicitud. La cadena base de firma será responsable de agregar estos encabezados dados a la firma para que formen parte de la MAC.
La autenticación de respuesta, cuando se realiza, solo cubre el cuerpo de la respuesta (carga útil) y parte de la información de la solicitud proporcionada por el cliente en su solicitud, como la marca de tiempo y el nonce. No cubre el código de estado HTTP ni ningún otro campo de encabezado de respuesta (por ejemplo, Ubicación) que pueda afectar el comportamiento del cliente.
Si un atacante puede manipular esta información y hacer que el cliente use una hora incorrecta, podría hacer que el cliente genere solicitudes autenticadas usando la hora en el futuro. Estas solicitudes fallarán cuando las envíe el cliente y probablemente no dejarán un rastro en el servidor (dada la implementación común de nonce, si es que se aplica). El atacante podrá entonces reproducir la solicitud en el momento correcto sin ser detectado.
Una solución a este problema sería sincronizar el reloj entre el cliente y el servidor. Para lograr esto, el servidor informa al cliente de su hora actual cuando se recibe una marca de tiempo no válida. Esto sucede en forma de encabezado de Fecha en la respuesta. Vea RFC2616 como motivación para esto.
El cliente sólo debe utilizar la información horaria proporcionada por el servidor si:
Al recibir una solicitud con una marca de tiempo incorrecta, el servidor proporciona al cliente su hora actual. El cliente nunca debe utilizar la hora recibida del servidor para ajustar su propio reloj, y sólo debe utilizarla para calcular un desplazamiento para comunicarse con ese servidor en particular.
HmacAuthentication valida la MAC de la solicitud entrante con el encabezado del host HTTP entrante. Un cliente malicioso puede crear nuevos nombres de host que apunten a la dirección IP del servidor y usarlos para diseñar un ataque enviando una solicitud válida destinada a otro nombre de host distinto al utilizado por el servidor. Los implementadores del servidor deben verificar manualmente que el encabezado del host recibido coincida con sus expectativas. Por ejemplo, si espera llamadas API en test.myapi.com, verifique que ese sea el dominio al que se envió la solicitud en la implementación del servidor.