Création d'une demande AWS d'API signée - AWS Identity and Access Management

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Création d'une demande AWS d'API signée

Important

Si vous utilisez un AWS SDK (voir Exemples de code et bibliothèques) ou un outil de ligne de AWS commande (CLI) pour envoyer des demandes d'API AWS, vous pouvez ignorer cette section car les clients du SDK et de la CLI authentifient vos demandes à l'aide des clés d'accès que vous fournissez. À moins que vous n'ayez une bonne raison de ne pas le faire, nous vous recommandons de toujours utiliser un kit SDK ou la CLI.

Dans les régions qui prennent en charge plusieurs versions de signature, les demandes de signature manuelle impliquent que vous devez spécifier la version de signature utilisée. Lorsque vous fournissez des demandes à des points d'accès multi-régions, les kits SDK et la CLI utiliseront automatiquement Signature version 4A sans configuration supplémentaire.

Voici un aperçu du processus de création d’une requête signée. Pour calculer une signature, vous avez d'abord besoin d'une chaîne à signer. Vous calculez ensuite un hachage HMAC-SHA256 de la chaîne à signer à l'aide d'une clé de signature. Le schéma suivant illustre le processus, y compris les différents composants de la chaîne que vous créez pour la signature.


                Image des parties d'une demande canonique, y compris la chaîne à signer, la clé de signature et la signature.

Le tableau suivant décrit les fonctions présentées dans le schéma. Vous devez implémenter du code pour ces fonctions. Pour plus d'informations, consultez les exemples de code dans les AWS SDK.

Fonction Description

Lowercase()

Convertit la chaîne en minuscules.

Hex()

Encodage en minuscules en base 16.

SHA256Hash()

Fonction de hachage cryptographique Secure Hash Algorithm (SHA, algorithme de hachage sécurisé).

HMAC-SHA256()

Calcule HMAC à l'aide de l'algorithme SHA256 avec la clé de signature fournie. Il s'agit de la signature finale.

Trim()

Supprimez tous les espaces blancs de début ou de fin.

UriEncode()

L'URI code chaque octet. UriEncode() doit appliquer les règles suivantes :

  • L'URI encode tous les octets sauf les caractères non réservés : A-Z, a-z, 0-9, -, ., _ et ~.

  • Le caractère d'espace est un caractère réservé qui doit être codé sous la forme « %20 » (et non sous la forme « + »).

  • Chaque octet encodé par URI est formé par un « % » et la valeur hexadécimale à deux chiffres de l'octet.

  • Les lettres de la valeur hexadécimale doivent être en majuscules, par exemple « %1A ».

  • Encodez la barre oblique « / » partout sauf dans le nom de la clé de l'objet. Par exemple, si le nom de clé de l'objet est photos/Jan/sample.jpg, la barre oblique du nom de la clé n'est pas encodée.

Important

Les UriEncode fonctions standard fournies par votre plate-forme de développement peuvent ne pas fonctionner en raison de différences de mise en œuvre et de l'ambiguïté associée dans les RFC sous-jacentes. Nous vous recommandons d'écrire votre propre UriEncode fonction personnalisée pour garantir le bon fonctionnement de votre encodage.

Pour voir un exemple de UriEncode fonction en Java, consultez la section Utilitaires Java sur le GitHub site Web.

Note

Lorsque vous signez vos demandes, vous pouvez utiliser la version 4 de AWS signature ou AWS la version 4A de signature. La principale différence entre les deux est déterminée par la façon dont la signature est calculée. Avec AWS la version 4A de Signature, la signature n'inclut pas d'informations spécifiques à la région et est calculée à l'aide de l'AWS 4-ECDSA-P256-SHA256algorithme.

informations d’identification de sécurité temporaires

Au lieu d'utiliser des informations d'identification à long terme pour signer une demande, vous pouvez utiliser des informations de sécurité temporaires fournies par AWS Security Token Service (AWS STS).

Lorsque vous utilisez des informations d'identification de sécurité temporaires, vous devez ajouterX-Amz-Security-Token à l'en-tête Authorization ou à la chaîne de requête pour contenir le jeton de session. Certains services nécessitent que vous ajoutiez X-Amz-Security-Token à la requête canonique. Pour les autres services, vous n’avez qu’à ajouter X-Amz-Security-Token à la fin, une fois que vous avez calculé la signature. Consultez la documentation de chacun Service AWS pour plus de détails.

Récapitulatif des étapes de signature

Étape 1 : créer une requête canonique

Organisez le contenu de votre demande (hôte, action, en-têtes, etc.) dans un format standard canonique. La demande canonique est l'une des entrées utilisées pour créer une chaîne de connexion. Pour plus de détails, consultez Éléments d'une signature de demande d' AWS API.

Étape 2 : créer un hachage de la requête canonique

Obtenez une clé de signature en effectuant une succession d'opérations de hachage par clé (opérations HMAC) à la date de la demande, dans la région et au service, avec votre clé d'accès AWS secrète comme clé pour l'opération de hachage initiale.

Étape 3 : créer une chaîne à signer

Créez une chaîne de connexion avec la demande canonique et des informations supplémentaires telles que l'algorithme, la date de la demande, la portée des informations d'identification et le digest (hachage) de la demande canonique.

Étape 4 : calculer la signature

Une fois la clé de signature dérivée, vous pouvez calculer la signature en exécutant une opération de hachage à clé sur la chaîne de connexion. Utilisez la clé de signature dérivée comme la clé de hachage pour cette opération.

Étape 5 : ajouter la signature à la requête

Une fois la signature calculée, ajoutez-la à un en-tête HTTP ou à la chaîne de requête de la demande.

Étape 1 : créer une requête canonique

Créez une requête canonique en concaténant les chaînes suivantes, séparées par des fins de ligne. Cela permet de garantir que la signature que vous calculez et la signature AWS calculée peuvent correspondre.

<HTTPMethod>\n <CanonicalURI>\n <CanonicalQueryString>\n <CanonicalHeaders>\n <SignedHeaders>\n <HashedPayload>
  • HTTPMethod : la méthode HTTP, telle que GET, PUT, HEAD et DELETE.

  • CanonicalUri— La version codée en URI de l'URI du composant du chemin absolu, en commençant par le «/» qui suit le nom de domaine et jusqu'à la fin de la chaîne ou jusqu'au point d'interrogation (« ? ») si vous avez des paramètres de chaîne de requête. Si le chemin d'accès absolu est vide, utilisez un caractère barre oblique (/). L'URI de l'exemple suivant, /examplebucket/myphoto.jpg, est le chemin absolu et vous n'encodez pas la « / » dans le chemin absolu :

    http://s3.amazonaws.com/examplebucket/myphoto.jpg
  • CanonicalQueryString— Les paramètres de chaîne de requête codés en URI. Vous encodez individuellement chaque nom et chaque valeur par URI. Vous devez également trier les paramètres de la chaîne de requête canonique par ordre alphabétique par nom de clé. Le tri s'effectue après l'encodage. La chaîne de requête dans l'exemple d'URI suivant est la suivante :

    http://s3.amazonaws.com/examplebucket?prefix=somePrefix&marker=someMarker&max-keys=2

    La chaîne de requête canonique est la suivante (des sauts de ligne sont ajoutés à cet exemple pour faciliter la lecture) :

    UriEncode("marker")+"="+UriEncode("someMarker")+"&"+ UriEncode("max-keys")+"="+UriEncode("20") + "&" + UriEncode("prefix")+"="+UriEncode("somePrefix")

    Lorsqu'une requête cible une sous-ressource, la valeur du paramètre de requête correspondant est une chaîne vide (« »). Par exemple, l'URI suivant identifie la sous-ressource ACL sur le compartiment examplebucket :

    http://s3.amazonaws.com/examplebucket?acl

    CanonicalQueryString Dans ce cas, c'est le suivant :

    UriEncode("acl") + "=" + ""

    Si l'URI ne contient pas de « ? » , la demande ne contient aucune chaîne de requête et vous définissez la chaîne de requête canonique sur une chaîne vide (« »). Vous devrez tout de même inclure le « \n ».

  • CanonicalHeaders— Liste des en-têtes de requêtes avec leurs valeurs. Les paires de nom et de valeur d'en-tête individuelles sont séparées par le caractère de saut de ligne (« \n »). Voici un exemple de CanonicalHeader :

    Lowercase(<HeaderName1>)+":"+Trim(<value>)+"\n" Lowercase(<HeaderName2>)+":"+Trim(<value>)+"\n" ... Lowercase(<HeaderNameN>)+":"+Trim(<value>)+"\n"

    CanonicalHeaders la liste doit inclure les éléments suivants :

    • En-tête host HTTP.

    • Si l'Content-Typeen-tête est présent dans la demande, vous devez l'ajouter à la CanonicalHeadersliste.

    • Les en-têtes x-amz-* que vous prévoyez d'inclure dans votre demande doivent également être ajoutés. Par exemple, si vous utilisez des informations d'identification de sécurité temporaires, vous devez inclure x-amz-security-token dans votre demande. Vous devez ajouter cet en-tête dans la liste des CanonicalHeaders.

    Note

    L'x-amz-content-sha256en-tête est obligatoire pour les AWS requêtes Amazon S3. Il fournit un hachage de la charge utile de la requête. S'il n'y a pas de charge utile, vous devez fournir le hachage d'une chaîne vide.

    Chaque nom d'en-tête doit :

    • utiliser des caractères minuscules ;

    • apparaître par ordre alphabétique ;

    • être suivi de deux points (:).

    Pour les valeurs, vous devez :

    • supprimer toutes les espaces de début ou de fin ;

    • convertir des espaces séquentielles en une espace unique ;

    • séparez les valeurs d'un en-tête à valeurs multiples par des virgules.

    • Vous devez inclure l'en-tête hôte (HTTP/1.1) ou l'en-tête :authority (HTTP/2), ainsi que tout en-tête x-amz-* dans la signature. Vous pouvez éventuellement inclure d'autres en-têtes standard dans la signature, tels que content-type.

    Les fonctions Lowercase() et Trim() utilisées dans cet exemple sont décrites dans la section précédente.

    L'exemple suivant est une chaîne CanonicalHeaders. Les noms d'en-tête sont en minuscules et sont triés.

    host:s3.amazonaws.com x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date:20130708T220855Z

    Note

    Aux fins du calcul d'une signature d'autorisation, seuls l'hôte et les en-têtes x-amz-* sont obligatoires. Toutefois, afin d'éviter toute altération des données, vous devez envisager d'inclure tous les en-têtes dans le calcul de la signature.

  • SignedHeaders— Une liste triée par ordre alphabétique et séparée par des points-virgules de noms d'en-têtes de demande en minuscules. Les en-têtes de demande de la liste sont les mêmes que ceux que vous avez inclus dans la chaîne CanonicalHeaders. Par exemple, pour l'exemple précédent, la valeur de SignedHeadersserait la suivante :

    host;x-amz-content-sha256;x-amz-date
  • HashedPayload— Chaîne créée à l'aide de la charge utile contenue dans le corps de la requête HTTP comme entrée d'une fonction de hachage. Cette chaîne utilise des caractères hexadécimaux minuscules.

    Hex(SHA256Hash(<payload>)

    Si la demande ne contient aucune charge utile, vous calculez un hachage de la chaîne vide comme suit :

    Hex(SHA256Hash(""))

    Le hachage renvoie la valeur suivante :

    e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

    Par exemple, lorsque vous chargez un objet à l'aide d'une demande PUT, vous fournissez les données de l'objet dans le corps du message. Lorsque vous récupérez un objet à l'aide d'une demande GET, vous calculez le hachage de la chaîne vide.

Étape 2 : créer un hachage de la requête canonique

Créez un hachage (digest) de la requête canonique avec le même algorithme que celui que vous avez utilisé pour créer le hachage de la charge utile. Le hachage de la requête canonique est une chaîne de caractères hexadécimaux en minuscules.

Étape 3 : créer une chaîne de connexion

Créez une chaîne en concaténant les chaînes suivantes, séparées par des fins de ligne. Ne terminez pas cette chaîne par un caractère de saut de ligne.

Algorithm \n RequestDateTime \n CredentialScope \n HashedCanonicalRequest
  • Algorithme : algorithme utilisé pour créer le hachage de la requête canonique. Pour SHA-256, l’algorithme est AWS4-HMAC-SHA256.

  • RequestDateTime— Date et heure utilisées dans le champ d'application des informations d'identification. Cette valeur est l'heure UTC actuelle au format ISO 8601 (par exemple, 20130524T000000Z).

  • CredentialScope— Le champ d'application des informations d'identification. Cela limite la signature résultante à la région et au service spécifiés. La chaîne a le format suivant : AAAAMMJJ/region/service/aws4_request.

  • HashedCanonicalRequest— Le hachage de la demande canonique. Cette valeur est calculée à l'étape 2.

L'exemple suivant est une chaîne de connexion.

"AWS4-HMAC-SHA256" + "\n" + timeStampISO8601Format + "\n" + <Scope> + "\n" + Hex(SHA256Hash(<CanonicalRequest>))

Étape 4 : calculer la signature

Dans AWS la version 4 de Signature, au lieu d'utiliser vos clés d' AWS accès pour signer une demande, vous créez une clé de signature limitée à une région et à un service spécifiques en tant qu'information d'authentification que vous ajouterez à votre demande.

DateKey = HMAC-SHA256("AWS4"+"<SecretAccessKey>", "<YYYYMMDD>") DateRegionKey = HMAC-SHA256(<DateKey>, "<aws-region>") DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>, "<aws-service>") SigningKey = HMAC-SHA256(<DateRegionServiceKey>, "aws4_request")

Pour obtenir la liste des chaînes régionales, veuillez consulter la rubrique Points de terminaison régionaux dans les Références générales AWS .

Pour chaque étape, appelez la fonction de hachage avec la clé et les données requises. Le résultat de chaque appel à la fonction de hachage devient l'entrée du prochain appel à la fonction de hachage.

Entrée obligatoire
  • Chaîne, Key, contenant votre clé d'accès secrète

  • Chaîne Date contenant la date utilisée dans l'étendue des informations d'identification, au format AAAAMMJJ

  • Chaîne, Region, contenant le code Région (par exemple, us-east-1)

  • Chaîne, Service, contenant le code de service (par exemple, ec2)

  • Chaîne de connexion que vous avez créée à l'étape précédente.

Pour calculer la signature
  1. Concaténez « AWS4 » et la clé d'accès secrète. Appelez la fonction de hachage avec la chaîne concaténée en tant que clé et la chaîne de date en tant que données.

    kDate = hash("AWS4" + Key, Date)
  2. Appelez la fonction de hachage en utilisant le résultat de l'appel précédent en tant que clé et la chaîne Région en tant que données.

    kRegion = hash(kDate, Region)
  3. Appelez la fonction de hachage en utilisant le résultat de l'appel précédent en tant que clé et la chaîne de service en tant que données.

    kService = hash(kRegion, Service)
  4. Appelez la fonction de hachage en utilisant le résultat de l'appel précédent en tant que clé et « aws4_request » en tant que données.

    kSigning = hash(kService, "aws4_request")
  5. Appelez la fonction de hachage en utilisant le résultat de l'appel précédent en tant que clé et la chaîne de signature en tant que données. Le résultat est la signature sous forme de valeur binaire.

    signature = hash(kSigning, string-to-sign)
  6. Convertissez la signature de la représentation binaire à la représentation hexadécimale, en caractères minuscules.

Étape 5 : ajouter la signature à la requête

Exemple : en-tête d'autorisation

L'exemple suivant montre un entête Authorization pour l'action DescribeInstances. Pour des raisons de lisibilité, cet exemple est formaté avec des sauts de ligne. Dans votre code, il doit s'agir d'une chaîne continue. Il n'y a pas de virgule entre l'algorithme et Credential. Toutefois, les autres éléments doivent être séparés par des virgules.

Authorization: AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20220830/us-east-1/ec2/aws4_request, SignedHeaders=host;x-amz-date, Signature=calculated-signature
Exemple : requête avec des paramètres d'authentification dans la chaîne de requête

L'exemple suivant présente une requête pour l'action DescribeInstances qui inclut les informations d'authentification. Pour des raisons de lisibilité, cet exemple est formaté avec des sauts de ligne et n’est pas code en URL. Dans votre code, la chaîne de requête doit être une chaîne continue codée en URL.

https://ec2.amazonaws.com/? Action=DescribeInstances& Version=2016-11-15& X-Amz-Algorithm=AWS4-HMAC-SHA256& X-Amz-Credential=AKIAIOSFODNN7EXAMPLE/20220830/us-east-1/ec2/aws4_request& X-Amz-Date=20220830T123600Z& X-Amz-SignedHeaders=host;x-amz-date& X-Amz-Signature=calculated-signature

Code source dans les AWS SDK

Les AWS SDK incluent le code source permettant de signer GitHub les demandes AWS d'API. Pour obtenir des exemples de code, veuillez consulter Exemples de projets dans le référentiel AWS d'échantillons