Règle HMAC

Cette page s'applique à Apigee et à Apigee hybrid.

Consultez la documentation d'Apigee Edge.

icône de la règle

Cette règle calcule et vérifie éventuellement un code HMAC (Hash-based Message Authentication Code). Parfois appelé "code d'authentification de message avec clé" ou "hachage avec clé", le HMAC utilise une fonction d'empreinte cryptographique telle que SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 ou MD-5 appliquée à un "message", avec une clé secrète pour produire une signature ou un code d'authentification de message sur ce message. Le terme "message" désigne ici un flux d'octets. En cas d'utilisation de HMAC, l'émetteur d'un message envoie un message et son HMAC à un destinataire. Ce dernier peut utiliser la clé HMAC et la clé secrète partagée pour authentifier le message.

Cette règle est une règle standard qui peut être déployée sur n'importe quel type d'environnement. Pour en savoir plus sur les types de règles et la disponibilité avec chaque type d'environnement, consultez la section Types de règles.

Pour en savoir plus sur HMAC, consultez la page HMAC : Keyed-Hashing for Message Authentication (rfc2104).

Exemples

Générer le HMAC

<HMAC name='HMAC-1'>

  <Algorithm>SHA256</Algorithm>

  <!-- the default encoding of the SecretKey is UTF-8 -->
  <SecretKey encoding='base64' ref='private.secretkey'/>

  <IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables> <!-- optional -->

  <!--
    The Message element accepts a template, which means the "message" the policy operates
    on can include fixed and multiple variable parts, including newlines and static functions.
    Whitespace, such as newlines and space characters, is significant.
   -->
  <Message>Fixed Part
{a_variable}
{timeFormatUTCMs(timeFormatString1,system.timestamp)}
{nonce}</Message>

  <!-- default encoding is base64 -->
  <Output encoding='base16'>name_of_variable</Output>

</HMAC>

Vérifier le HMAC

<HMAC name='HMAC-1'>

  <Algorithm>SHA256</Algorithm>

  <!-- the default encoding of the SecretKey is UTF-8 -->
  <SecretKey encoding='base16' ref='private.secretkey'/>

  <IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables> <!-- optional -->

  <!--
     The Message element accepts a template. This policy verifies an HMAC on the request content.
   -->
  <Message>{request.content}</Message>

  <!--
    VerificationValue is optional.
    Include it to perform an HMAC check.
  -->
  <VerificationValue encoding='base16' ref='expected_hmac_value'/>

  <!-- default encoding of the output is base64 -->
  <Output encoding='base16'>name_of_variable</Output>

</HMAC>

Le calcul d'une signature et la vérification de cette signature suit exactement le même processus. La règle HMAC calcule un HMAC et peut éventuellement vérifier la signature calculée par rapport à une valeur attendue. L'élément facultatif VerificationValue (le cas échéant) dirige la règle pour comparer la valeur calculée à une valeur connue ou donnée.


Référence d'élément pour HMAC

La référence de la règle décrit les éléments et les attributs de la règle HMAC.

Attributs qui s'appliquent à l'élément de premier niveau

<HMAC name="HMAC" continueOnError="false" enabled="true" async="false">

Les attributs suivants sont communs à tous les éléments parents de la stratégie.

Attribut Description Par défaut Presence
nom Nom interne de la stratégie. Les caractères que vous pouvez utiliser dans le nom se limitent à : A-Z0-9._\-$ %. L'interface utilisateur Apigee applique cependant des restrictions supplémentaires, telles que la suppression automatique des caractères qui ne sont pas alphanumériques.

Vous pouvez également utiliser l'élément <DisplayName> pour ajouter un libellé à la règle dans l'éditeur de proxy de l'interface utilisateur d'Apigee, en utilisant un nom différent, en langage naturel.

ND Obligatoire
continueOnError Définissez sur false pour afficher une erreur en cas d'échec d'une stratégie. Il s'agit du comportement attendu pour la plupart des règles.

Définissez sur true pour que l'exécution du flux se poursuive même après l'échec d'une règle. Voir également :

false Facultatif
activé Définissez la valeur sur true pour appliquer la stratégie.

Définissez la valeur sur false pour "désactiver" la stratégie. La stratégie ne sera pas appliquée même si elle reste associée à un flux.

true Facultatif
async Cet attribut est obsolète. false Obsolète

<Algorithm>

<Algorithm>algorithm-name</Algorithm>

Spécifie l'algorithme de hachage à utiliser lors du calcul du code HMAC.

Par défaut ND
Presence Obligatoire
Type Chaîne
Valeurs valides SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, et MD-5

La configuration de la règle accepte les noms d'algorithme sans distinction de casse, et avec ou sans le tiret entre les lettres et les chiffres. Par exemple, SHA256, SHA-256 et sha256 sont équivalents.

<DisplayName>

<DisplayName>Policy Display Name</DisplayName>

À utiliser, en plus de l'attribut, pour appliquer un libellé à la règle dans l'éditeur de proxy de l'interface utilisateur d'Apigee en utilisant un nom différent, en langage naturel.

Par défaut Si vous omettez cet élément, la valeur de l'attribut de nom de la stratégie est utilisée.
Presence Facultatif
Type Chaîne

<Message>

<Message>message_template_here</Message>
or
<Message ref='variable_here'/>

Spécifie la charge utile du message à signer. L'entrée de cet élément est compatible avec les modèles de message (substitution de variable) pour permettre l'inclusion d'éléments supplémentaires lors de l'exécution, tels que l'horodatage, les nonces, les listes d'en-têtes ou d'autres informations. Exemple :

<Message>Fixed Part
    {a_variable}
    {timeFormatUTCMs(timeFormatString1,system.timestamp)}
    {nonce}
</Message>

Le modèle de message peut inclure des parties fixes et variables, y compris des nouvelles lignes et des fonctions statiques. Les espaces blancs, tels que les sauts de ligne et les caractères d'espacement, sont importants.

Par défaut ND
Presence Obligatoire
Type Chaîne
Valeurs valides Toute chaîne est valide pour la valeur de texte. Si vous fournissez un attribut ref, il est prioritaire sur la valeur de texte. La règle évalue la valeur textuelle ou la variable référencée en tant que modèle de message.

<Output>

<Output encoding='encoding_name'>variable_name</Output>

Spécifie le nom de la variable que la règle doit définir avec la valeur HMAC calculée. Spécifie également l'encodage à utiliser pour la sortie.

Par défaut

La variable de sortie par défaut est hmac.POLICYNAME.output.

La valeur par défaut de l'attribut encoding est base64.

Presence Facultatif. Si cet élément est absent, la règle définit la variable de flux hmac.POLICYNAME.output avec une valeur encodée en base64.
Type Chaîne
Valeurs valides

Pour l'encodage, hex, base16, base64, base64url.

Les valeurs ne sont pas sensibles à la casse. hex et base16 sont des synonymes.

La valeur textuelle de l'élément Output peut être n'importe quel nom de variable de flux valide.

<SecretKey>

<SecretKey encoding='encoding_name' ref='private.secretkey'/>

Spécifie la clé secrète utilisée pour calculer le HMAC. La clé est obtenue à partir de la variable référencée, décodée en fonction de l'encodage spécifique.

Par défaut

Il n'existe pas de valeur par défaut pour la variable référencée. L'attribut ref est obligatoire.

En l'absence d'attribut encoding, la règle décode par défaut la chaîne de clé secrète avec UTF-8 pour obtenir les octets de clés.

Presence Obligatoire
Type Chaîne
Valeurs valides

Pour encoding, les valeurs valides sont hex, base16, base64 et utf8. Le codage par défaut est UTF8. Les valeurs ne sont pas sensibles à la casse, et les tirets ne sont pas significatifs. Base16 est identique à base-16 et bAse16. Base16 et Hex sont des synonymes.

L'utilisation d'un attribut d'encodage vous permet de spécifier une clé qui inclut des octets en dehors de la plage de caractères imprimables UTF-8. Par exemple, supposons que la configuration de la règle inclut ce qui suit :

 <SecretKey encoding='hex' ref='private.encodedsecretkey'/>

Et supposons que private.encodedsecretkey contienne la chaîne 536563726574313233.

Dans ce cas, les octets de clés sont décodés comme : [53 65 63 72 65 74 31 32 33] (chaque octet représenté eau format hexadécimal). Autre exemple : si vous utilisez encoding='base64' et si private.encodedsecretkey contient la chaîne U2VjcmV0MTIz, le même ensemble d'octets sera obtenu pour la clé. Sans attribut d'encodage, ou avec un attribut d'encodage de UTF8, la valeur de chaîne Secret123 donne le même ensemble d'octets. Cette section présente trois méthodes différentes pour représenter la même clé.

<VerificationValue>

<VerificationValue encoding='encoding_name' ref='variable_name'/>
or
<VerificationValue encoding='encoding_name'>string_value</VerificationValue>

(Facultatif) Spécifie la valeur de validation, ainsi que l'encodage utilisé pour encoder la valeur de validation. La règle utilise cet encodage pour décoder la valeur.

Par défaut Il n'existe aucune valeur de validation par défaut. Si l'élément est présent, mais que l'attribut encoding est absent, la règle utilise l'encodage par défaut base64
Presence Facultatif
Type Chaîne
Valeurs valides

Voici des valeurs valides pour l'attribut d'encodage : hex, base16, base64, base64url. Les valeurs ne sont pas sensibles à la casse. hex et base16 sont des synonymes.

L'encodage de VerificationValue ne doit pas nécessairement être identique à celui utilisé pour l'élément Output.

<IgnoreUnresolvedVariables>

<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>

Définissez la valeur sur false si vous souhaitez que la règle génère une erreur lorsqu'une variable référencée spécifiée dans la stratégie est irrésolue. Définissez la valeur sur true pour traiter toute variable irrésolue comme une chaîne vide (null).

La valeur booléenne IgnoreUnresolvedVariables n'affecte que les variables référencées par le modèle de message. Si SecretKey et VerificationValue peuvent faire référence à une variable, chacune d'entre elles doit être résolue, le paramètre ignore ne s'applique donc pas à ces variables.

Par défaut Faux
Presence Facultatif
Type Booléen
Valeurs valides True ou False

Variables de flux

La règle peut définir ces variables lors de l'exécution.

Variable Description Exemple
hmac.policy_name.message La règle définit cette variable avec le message effectif, c'est-à-dire le résultat de l'évaluation du modèle de message spécifié dans l'élément Message. hmac.HMAC-Policy.message = "Hello, World"
hmac.policy_name.output Récupère le résultat du calcul HMAC lorsque l'élément Output ne spécifie pas de nom de variable. hmac.HMAC-Policy.output = /yyRjydfP+fBHTwXFgc5AZhLAg2kwCri+e35girrGw4=
hmac.policy_name.outputencoding Récupère le nom de l'encodage de sortie. hmac.HMAC-Policy.outputencoding = base64

Problèmes courants

À un niveau, la règle HMAC semble simple : fournissez une clé et un message, puis obtenez un code HMAC calculé en réponse. L'utilisation de la règle peut s'avérer frustrante si vous obtenez une valeur HMAC inattendue pour une combinaison de messages et de clés connue. Cette section explique certaines notes d'utilisation permettant de résoudre de tels problèmes.

Deux problèmes courants peuvent entraîner des erreurs HMAC lors de la validation : les différences d'espaces dans le message et les différences d'encodage et de décodage. La seconde s'applique à l'élément SecretKey ainsi qu'à l'élément Output.

Différences entre espaces blancs

Les différences qui peuvent sembler sans importance pour un humain affectent la valeur HMAC de sortie. Par exemple, supposons qu'une clé secrète puisse être représentée sous la forme "Secret123". Avec le décodage UTF-8, les octets de clé seront les suivants : [53 65 63 72 65 74 31 32 33]. Utiliser cette clé pour calculer un HMAC-SHA256 sur le message abc donne a7938720fe5749d31076e6961360364c0cd271443f1b580779932c244293bc94. L'ajout d'un seul espace au message afin qu'il soit de type abc<SPACE>, où <SPACE> implique un code ASCII 32, génère un HMAC-SHA256 de 274669b2a85d2532da48e2ce3d8e52ee17346d1bcd1a606d87db1934b5ab294b.

De même, si le message est abc<NEWLINE>, où <NEWLINE> implique un code ASCII 10, le code HMAC est 0780370844ca07f896066837e8230d3b6a775f678a4ae03e6b5e864c674831f5. De légères modifications du message entraînent des valeurs HMAC très différentes. Cela est volontaire. Il s'agit d'un comportement HMAC souhaité.

Ce qu'il faut retenir : il est important de s'assurer que le corps du message utilisé pour calculer le HMAC d'origine et le corps du message utilisé pour vérifier le HMAC sont exactement les mêmes. Si l'outil de vérification d'un HMAC modifie la charge utile des messages d'une manière ou d'une autre, en ajoutant des espaces ou en reformatant le texte, le HMAC calculé change.

Soyez particulièrement vigilant lorsque vous utilisez un modèle de message dans la configuration de la règle. Par exemple, le fragment de configuration de stratégie suivant présente un problème potentiel :

<HMAC name='HMAC-1'>
    ...
    <!-- the result of this message template will include surrounding whitespace -->
    <Message>
        {request.content}
    </Message>
    ...
       
</HMAC>

Le résultat de l'évaluation du modèle de message dans l'élément <Message> inclut les sauts de ligne et les espaces entourant le contenu du message. Ce n'est probablement pas prévu. Une meilleure configuration se présenterait comme suit :

<HMAC name='HMAC-1'>
    ...
    <Message>{request.content}</Message>
    ...
         
</HMAC>

Différences d'encodage

Des décodages différents du même matériel de clé génèrent des clés différentes. Supposons qu'une clé secrète puisse être représentée par "U2VjcmV0S2V5MTIz". Avec le décodage UTF-8, les octets de clé tels que représentés en base16 sont : [55 32 56 6a 63 6d 56 30 53 32 56 35 4d 54 49 7a]. Avec le décodage en base64, les octets de clé seront [53 65 63 72 65 74 4b 65 79 31 32 33]. Le décodage du matériel source génère des clés différentes et génère des valeurs HMAC différentes.

Ce qu'il faut retenir : il est important de s'assurer que le matériel de clé utilisé pour calculer le HMAC d'origine et la clé utilisée pour vérifier le HMAC sont exactement les mêmes. Cela signifie probablement que le même encodage de la clé est utilisé aux deux extrémités. Dans la règle HMAC, vous pouvez utiliser l'attribut encoding sur l'élément SecretKey pour spécifier l'encodage de la clé.

Pensez également aux encodages sur la sortie. HMAC-SHA256 exprimé en base16 ou encodage hexadécimal en 27f17e11c8ece93844c5eb5e55161d993368628a214f9a51c25d0185e8ea06e2 est identique à un HMAC-SHA256 exprimé au format base64 en tant que J/F+Ecjs6ThExeteVRYdmTNoYoohT5pRwl0BhejqBuI=. Elles se présentent différemment, mais ces deux chaînes représentent la même valeur. Assurez-vous que le même encodage est utilisé pour encoder le code HMAC et le code HMAC de validation. Dans la règle HMAC, vous pouvez utiliser l'attribut encoding sur l'élément Output pour spécifier l'encodage de sortie souhaité et le même attribut sur l'élément VerificationValue pour spécifier comment décoder l'outil de vérification.

Informations de référence sur les erreurs

Cette section décrit les codes d'erreur et les messages d'erreur renvoyés et les variables d'erreur définies par Apigee lorsque cette règle déclenche une erreur. Ces informations sont importantes si vous développez des règles de défaillance afin de gérer les pannes. Pour en savoir plus, consultez les pages Ce que vous devez savoir à propos des erreurs liées aux règles et Gérer les pannes.

Erreurs d'exécution

Ces erreurs peuvent se produire lors de l'exécution de la règle.

Code d'erreur État HTTP Se produit quand
steps.hmac.UnresolvedVariable 401

Cette erreur se produit si une variable spécifiée dans la règle HMAC est :

  • est hors de portée (non disponible dans le flux spécifique où la règle est exécutée)

    ou

  • impossible à résoudre (non définie).
steps.hmac.HmacVerificationFailed 401 Échec de la vérification du code HMAC. La valeur de la vérification fournie ne correspond pas à la valeur calculée.
steps.hmac.HmacCalculationFailed 401 La règle n'a pas pu calculer le code HMAC.
steps.hmac.EmptySecretKey 401 La valeur de la variable de clé secrète est vide.
steps.hmac.EmptyVerificationValue 401 La variable contenant la valeur de la vérification est vide.

Erreurs de déploiement

Ces erreurs peuvent se produire lorsque vous déployez un proxy contenant cette règle.

Nom de l'erreur État HTTP Se produit quand
steps.hmac.MissingConfigurationElement 401 Cette erreur se produit lorsqu'un élément ou un attribut obligatoire est manquant.
steps.hmac.InvalidValueForElement 401 Cette erreur se produit si la valeur spécifiée dans l'élément "Algorithm" n'est pas l'une des valeurs suivantes : SHA-1, SHA-224, SHA-256, SHA-512 ou MD-5.
steps.hmac.InvalidSecretInConfig 401 Cette erreur se produit si une valeur textuelle est explicitement fournie pour SecretKey.
steps.hmac.InvalidVariableName 401 Cette erreur se produit si la variable SecretKey ne contient pas le préfixe private (private.).

Variables de panne

Ces variables sont définies lorsqu'une erreur d'exécution se produit. Pour en savoir plus, consultez la section Ce que vous devez savoir sur les erreurs liées aux règles.

Variables Lieu Exemple
fault.name="fault_name" fault_name est le nom de l'erreur, tel qu'indiqué dans le tableau Erreurs d'exécution ci-dessus. Le nom d'erreur est la dernière partie du code d'erreur. fault.name Matches "UnresolvedVariable"
hmac.policy_name.failed La règle définit cette variable en cas d'échec. hmac.HMAC-Policy.failed = true

Exemple de réponse d'erreur

Pour le traitement des erreurs, la meilleur pratique consiste à intercepter la partie errorcode de la réponse. Ne vous fiez pas au texte dans faultstring, car il pourrait changer.

Exemple de règle de défaillance

<FaultRules>
    <FaultRule name="HMAC Policy Errors">
        <Step>
            <Name>AM-Unauthorized</Name>
            <Condition>(fault.name Matches "HmacVerificationFailed")</Condition>
        </Step>
        <Condition>hmac.HMAC-1.failed = true</Condition>
    </FaultRule>
</FaultRules>