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 Exemple de code et bibliothèques) ou un outil AWS Command Line Interface (AWS 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 envoyez des demandes à des points d'accès multirégionaux, SDKs la CLI passe automatiquement à l'utilisation de Signature Version 4A sans configuration supplémentaire.

Vous pouvez utiliser le protocole de signature AWS SigV4 pour créer une demande signée pour les demandes AWS d'API.

  1. Création d’une requête canonique basée sur les détails de la requête.

  2. Calcul d'une signature à l'aide de vos AWS informations d'identification.

  3. Ajout de cette signature à la requête en tant qu’en-tête Autorisation.

AWS reproduit ensuite ce processus et vérifie la signature, en accordant ou en refusant l'accès en conséquence.

Pour savoir comment utiliser AWS SigV4 pour signer des demandes d'API, consultezDemander des exemples de signature.

Le tableau suivant décrit les fonctions utilisées lors de la création d'une demande signée. Vous devez implémenter du code pour ces fonctions. Pour plus d'informations, consultez les exemples de code dans le AWS SDKs.

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 le HMAC en utilisant l' SHA256 algorithme avec la clé de signature fournie. Il s'agit de la signature finale lorsque vous signez avec SigV4.

ECDSA-Sign

Signature de l'algorithme de signature numérique à courbe elliptique (ECDSA) calculée à l'aide de signatures asymétriques basées sur la cryptographie à clé publique-privée.

KDF(K, Label, Context, L)

Un KDF NIST SP8 00-108 en mode compteur utilisant la fonction PRF HMAC- telle SHA256 que définie dans le NIST SP 800-108r1.

Oct2Int(byte[ ])

Fonction octet par entier telle que décrite dans la norme ANSI X9.62.

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 plateforme de développement peuvent ne pas fonctionner en raison de différences de mise en œuvre et de l'ambiguïté associée au niveau du sous-jacent RFCs. 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 AWS SigV4 ou AWS SigV4a. La principale différence entre les deux est déterminée par la façon dont la signature est calculée. Avec SigV4a, l'ensemble de régions est inclus dans la chaîne à signer, mais ne fait pas partie de l'étape de dérivation des informations d'identification.

Requêtes de signature avec des 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 ajouter X-Amz-Security-Token à l’en-tête Autorisation ou l’inclure à 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 connaître les exigences spécifiques.

Récapitulatif des étapes de signature

Création d’une requête canonique

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

Création d’un hachage de la requête canonique

Hashez la requête canonique avec le même algorithme que celui que vous avez utilisé pour créer le hachage des données utiles. Le hachage de la requête canonique est une chaîne de caractères hexadécimaux en minuscules.

Création d’une chaîne à signer

Créez une chaîne de connexion avec la requête canonique et des informations supplémentaires telles que l’algorithme, la date de la requête, la portée des informations d’identification et le hachage de la requête canonique.

Dérivation d’une clé de signature

Utilisez la clé d'accès secrète pour obtenir la clé utilisée pour signer la demande.

Calcul de la signature

Effectuez une opération de hachage par clé sur la chaîne à signer en utilisant la clé de signature dérivée comme clé de hachage.

Ajout d’une signature à la requête

Ajouter la signature calculée à un en-tête HTTP ou à la chaîne de requête de la requête.

Création d’une requête canonique

Pour créer une requête canonique, concaténez les chaînes suivantes, séparées par des caractères de saut de ligne. Cela permet de garantir que la signature que vous calculez peut correspondre à la signature AWS calculée.

<HTTPMethod>\n <CanonicalURI>\n <CanonicalQueryString>\n <CanonicalHeaders>\n <SignedHeaders>\n <HashedPayload>
  • HTTPMethod— La méthode HTTP, telle que GETPUT,HEAD, etDELETE.

  • CanonicalUri— Version codée en URI de l'URI du composant du chemin absolu, en commençant par / celui 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, /amzn-s3-demo-bucket/myphoto.jpg, est le chemin absolu et vous n’encodez pas la / dans le chemin absolu :

    http://s3.amazonaws.com/amzn-s3-demo-bucket/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/amzn-s3-demo-bucket?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 amzn-s3-demo-bucket :

    http://s3.amazonaws.com/amzn-s3-demo-bucket?acl

    Dans ce cas, il s' CanonicalQueryString agirait de :

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

    Si l’URI ne contient pas de ?, la requête 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 caractère de saut de ligne ("\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 CanonicalHeaders liste.

    • 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 desCanonicalHeaders.

    • Pour Sigv4a, vous devez inclure un en-tête d'ensemble de régions qui indique l'ensemble de régions dans lesquelles la demande sera valide. L'en-tête X-Amz-Region-Set est spécifié sous la forme d'une liste de valeurs séparées par des virgules. L'exemple suivant montre un en-tête de région qui permet d'effectuer une demande à la fois dans les régions us-east-1 et us-west-1.

      X-Amz-Region-Set=us-east-1,us-west-1

      Vous pouvez utiliser des caractères génériques (*) dans les régions pour spécifier plusieurs régions. Dans l'exemple suivant, l'en-tête permet de faire une demande à la fois dans us-west-1 et us-west-2.

      X-Amz-Region-Set=us-west-*

    Note

    L’en-tête x-amz-content-sha256 est obligatoire pour les requêtes AWS 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

    Pour calculer une signature d'autorisation, seuls l'hôte et les x-amz-* en-têtes éventuels sont nécessaires ; toutefois, afin d'éviter toute altération des données, vous devez envisager d'inclure des en-têtes supplémentaires dans le calcul de la signature.

    N'incluez pas hop-by-hop les en-têtes fréquemment modifiés lors du transit dans un système complexe. Cela inclut tous les en-têtes de transport volatils qui sont mutés par les proxys, les équilibreurs de charge et les nœuds d'un système distribué, y comprisconnection,x-amzn-trace-id,user-agent,keep-alive,transfer-encoding, TEtrailer, upgrade et. proxy-authorization proxy-authenticate

  • 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. Dans l'exemple précédent, la valeur de SignedHeaders serait 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 requête ne contient pas de données utiles, vous calculez un hachage de la chaîne vide, comme lorsque vous récupérez un objet à l’aide d’une requête GET, il n’y a rien dans les données utiles.

    Hex(SHA256Hash(""))
    Note

    Pour Amazon S3, incluez la chaîne littérale UNSIGNED-PAYLOAD lors de la création d’une requête canonique, et définissez la même valeur que celle de l’en-tête x-amz-content-sha256 lors de l’envoi de la requête.

    Hex(SHA256Hash("UNSIGNED-PAYLOAD"))

Création d’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.

Création d’une chaîne à signer

Pour créer une chaîne, concaténez les chaînes suivantes, séparées par des sauts de ligne. Ne terminez pas cette chaîne par un caractère de saut de ligne.

Algorithm \n RequestDateTime \n CredentialScope \n HashedCanonicalRequest
  • Algorithm— Algorithme utilisé pour créer le hachage de la demande canonique.

    • SigV4 — AWS4-HMAC-SHA256 À utiliser pour spécifier l'algorithme de HMAC-SHA256 hachage.

    • SigV4a — AWS4-ECDSA-P256-SHA256 À utiliser pour spécifier l'algorithme de ECDSA-P256-SHA-256 hachage.

  • 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— L'étendue des informations d'identification, qui limite la signature résultante à la région et au service spécifiés.

    • SigV4 — Les informations d'identification incluent l'identifiant de votre clé d'accès, la date au YYYYMMDD format, le code de région, le code de service et la chaîne de aws4_request fin, séparés par des barres obliques (/). Le code Région, le code de service et la chaîne de terminaison doivent utiliser des caractères minuscules. La chaîne a le format suivant :YYYYMMDD/region/service/aws4_request.

    • SigV4a — Les informations d'identification incluent le YYYYMMDD format de la date, le nom du service et la chaîne de aws4_request fin, séparés par des barres obliques (/). Notez que l'étendue des informations d'identification n'inclut pas la région car celle-ci est couverte dans un en-tête X-Amz-Region-Set distinct. La chaîne a le format suivant :YYYYMMDD/service/aws4_request.

  • HashedCanonicalRequest— Le hachage de la demande canonique, calculé à l'étape précédente.

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

"<Algorithm>" + "\n" + timeStampISO8601Format + "\n" + <Scope> + "\n" + Hex(<Algorithm>(<CanonicalRequest>))

Dérivation d’une clé de signature

Pour obtenir une clé de signature, choisissez l'un des processus suivants afin de calculer une clé de signature pour SigV4 ou SigV4a.

Dérivation d'une clé de signature pour SigV4

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

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.

L’exemple suivant montre comment vous obtenez la SigningKey utilisée dans la section suivante de cette procédure, en indiquant l’ordre dans lequel vos données sont concaténées et hachées. HMAC-SHA256 est la fonction de hachage utilisée pour hacher les données comme indiqué.

DateKey = HMAC-SHA256("AWS4"+"<SecretAccessKey>", "<YYYYMMDD>") DateRegionKey = HMAC-SHA256(<DateKey>, "<aws-region>") DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>, "<aws-service>") SigningKey = HMAC-SHA256(<DateRegionServiceKey>, "aws4_request")
Entrée obligatoire
  • Key— Chaîne contenant votre clé d'accès secrète.

  • Date— Chaîne contenant la date utilisée dans le champ d'application des informations d'identification, au format YYYYMMDD.

  • Region— Chaîne contenant le code de région (par exemple,us-east-1).

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

  • Service— Chaîne contenant le code du service (par exemple,ec2).

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

Pour dériver une clé de signature pour SigV4
  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.

    DateKey = 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.

    DateRegionKey = 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.

    Le code de service est défini par le service. Vous pouvez utiliser get-products dans l’interface de ligne de commande de tarification AWS pour renvoyer le code de service d’un service.

    DateRegionServiceKey = 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.

    SigningKey = hash(kService, "aws4_request")

Dérivation d'une clé de signature pour SigV4A

Pour créer une clé de signature pour SigV4a, utilisez le processus suivant pour dériver une paire de clés à partir de la clé d'accès secrète. Pour un exemple d'implémentation de cette dérivation, voir l'implémentation de l'authentification côté client dans la bibliothèque C99 AWS

n = [NIST P-256 elliptic curve group order] G = [NIST P-256 elliptic curve base point] label = "AWS4-ECDSA-P256-SHA256" akid = [AWS access key ID as a UTF8 string] sk = [AWS secret access Key as a UTF8 Base64 string] input_key = "AWS4A" || sk count = 1 while (counter != 255) { context = akid || counter // note: counter is one byte key = KDF(input_key, label, context, 256) c = Oct2Int(key) if (c > n - 2) { counter++ } else { k = c + 1 // private key Q = k * G // public key } } if (c < 255) { return [k, Q] } else { return FAILURE }

Calcul de la signature

Une fois que vous avez obtenu la clé de signature, calculez la signature à ajouter à votre demande. Cette procédure varie en fonction de la version de signature que vous utilisez.

Pour calculer une signature pour SigV4
  1. Appelez la fonction de hachage avec le résultat de l'appel précédent comme clé et la chaîne à signer comme donnée. Utilisez la clé de signature dérivée comme la clé de hachage pour cette opération. Le résultat est la signature sous forme de valeur binaire.

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

Pour calculer une signature pour SigV4a
  1. À l'aide de l'algorithme de signature numérique (ECDSA P-256), signez la chaîne de signature que vous avez créée à l'étape précédente. La clé utilisée pour cette signature est la clé asymétrique privée dérivée de la clé d'accès secrète telle que décrite ci-dessus.

    signature = base16(ECDSA-Sign(k, string-to-sign))
  2. Convertissez la signature de la représentation binaire à la représentation hexadécimale, en caractères minuscules.

Ajout d’une signature à la requête

Ajoutez la signature calculée à votre demande.

Exemple : en-tête d'autorisation
SigV4

L'exemple suivant montre un Authorization en-tête pour l'DescribeInstancesaction utilisant AWS SigV4. 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
SigV4a

L'exemple suivant montre un en-tête d'autorisation pour l'CreateBucketaction utilisant AWS SigV4a. 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-ECDSA-P256-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20220830/s3/aws4_request, SignedHeaders=host;x-amz-date;x-amz-region-set, Signature=calculated-signature
Exemple : requête avec des paramètres d'authentification dans la chaîne de requête
SigV4

L'exemple suivant montre une requête pour l'DescribeInstancesaction utilisant AWS SigV4 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
SigV4a

L'exemple suivant montre une requête pour l'CreateBucketaction utilisant AWS SigV4a 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=CreateBucket& Version=2016-11-15& X-Amz-Algorithm=AWS4-ECDSA-P256-SHA256& X-Amz-Credential=AKIAIOSFODNN7EXAMPLE/20220830/s3/aws4_request& X-Amz-Region-Set=us-west-1& X-Amz-Date=20220830T123600Z& X-Amz-SignedHeaders=host;x-amz-date;x-amz-region-set& X-Amz-Signature=calculated-signature