View a markdown version of this page

Calculs de signature pour l'en-tête d'autorisation : transfert de la charge utile en plusieurs segments (téléchargement fragmenté) (AWS Signature (version 4) - Amazon Simple Storage Service

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.

Calculs de signature pour l'en-tête d'autorisation : transfert de la charge utile en plusieurs segments (téléchargement fragmenté) (AWS Signature (version 4)

Comme décrit dans leVue d’ensemble, lorsque vous authentifiez des demandes à l'aide de l'Authorizationen-tête, vous avez la possibilité de télécharger la charge utile par morceaux. Vous pouvez envoyer des données en blocs de taille fixe ou variable. Cette section décrit le processus de calcul de la signature lors d'un téléchargement fragmenté, comment créer le corps du bloc et comment fonctionne la signature différée lorsque vous chargez le bloc pour la première fois et que vous envoyez sa signature dans le bloc suivant. La section d'exemple (voirExemple : objet PUT) présente les calculs de signature et Authorization les en-têtes qui en résultent, que vous pouvez utiliser comme suite de tests pour vérifier votre code.

Note

Lorsque vous transférez des données en plusieurs segments, vous devez effectuer l'une des opérations suivantes :

  • Spécifiez explicitement la longueur totale du contenu (longueur de l'objet en octets plus les métadonnées de chaque bloc) à l'aide de l'en-tête Content-Length HTTP. Pour ce faire, vous devez précalculer la longueur totale de la charge utile, y compris les métadonnées que vous envoyez dans chaque bloc, avant de lancer votre demande.

  • Spécifiez l'en-tête Transfer-Encoding HTTP. Si vous incluez l'Transfer-Encodingen-tête et que vous spécifiez une valeur différenteidentity, vous devez omettre l'Content-Lengthen-tête.

Pour toutes les demandes, vous devez inclure l'x-amz-decoded-content-lengthen-tête, en spécifiant la taille de l'objet en octets.

Le calcul de la signature de chaque segment inclut la signature du segment précédent. Pour commencer, vous devez créer une signature initiale en utilisant uniquement les en-têtes. Vous utilisez la signature initiale dans le calcul de la signature du premier segment. Pour chaque segment suivant, vous créez une signature de bloc qui inclut la signature du bloc précédent. Ainsi, les signatures de bloc sont enchaînées ; c'est-à-dire que la signature du bloc n est une fonction F (bloc n, signature (bloc n-1)). Le chaînage garantit que vous envoyez les morceaux dans le bon ordre.

Pour effectuer un téléchargement fragmenté, procédez comme suit :

  1. Décidez de la taille du bloc de charge utile. Vous en avez besoin lorsque vous écrivez le code.

    La taille du bloc doit être d'au moins 8 Ko. Nous recommandons une taille de bloc d'au moins 64 Ko pour de meilleures performances. Cette taille de bloc s'applique à tous les morceaux sauf le dernier. Le dernier bloc que vous envoyez peut être inférieur à 8 Ko. Si votre charge utile est petite et peut tenir dans un seul bloc, elle peut être inférieure aux 8 Ko.

  2. Créez la signature de départ à inclure dans le premier bloc. Pour de plus amples informations, veuillez consulter Calcul de la signature de la graine.

  3. Créez le premier morceau et diffusez-le. Pour de plus amples informations, veuillez consulter Définition du corps du morceau.

  4. Pour chaque segment suivant, calculez la signature du segment qui inclut la signature précédente dans la chaîne que vous signez, construisez le morceau et envoyez-le. Pour de plus amples informations, veuillez consulter Définition du corps du morceau.

  5. Envoyez le dernier bloc supplémentaire, qui est le même que les autres morceaux de la construction, mais il ne contient aucun octet de données. Pour de plus amples informations, veuillez consulter Définition du corps du morceau.

Calcul de la signature de la graine

Le schéma suivant illustre le processus de calcul de la signature initiale.

Processus de calcul de la signature de départ.

Le tableau suivant décrit les fonctions présentées dans le schéma. Vous devez implémenter du code pour ces fonctions.

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 plateforme de développement peuvent ne pas fonctionner en raison de différences d'implémentation et de l'ambiguïté associée dans les RFC sous-jacents. Nous vous recommandons d'écrire votre propre UriEncode fonction personnalisée pour garantir le bon fonctionnement de votre encodage.

Voici un exemple de fonction UriEncode () en Java.

public static String UriEncode(CharSequence input, boolean encodeSlash) { StringBuilder result = new StringBuilder(); for (int i = 0; i < input.length(); i++) { char ch = input.charAt(i); if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-' || ch == '~' || ch == '.') { result.append(ch); } else if (ch == '/') { result.append(encodeSlash ? "%2F" : ch); } else { result.append(toHexUTF8(ch)); } } return result.toString(); }

Pour plus d'informations sur le processus de signature, consultezCalculs de signature pour l'en-tête d'autorisation : transfert de la charge utile en un seul bloc (AWS Signature (version 4). Le processus est le même, sauf que la création de CanonicalRequest diffère comme suit :

  • Outre les en-têtes de demande que vous prévoyez d'ajouter, vous devez inclure les en-têtes suivants :

    En-tête Description
    x-amz-content-sha256

    Cet en-tête est obligatoire pour toutes les demandes AWS Signature Version 4. Définissez la valeur sur STREAMING-AWS4-HMAC-SHA256-PAYLOAD pour indiquer que la signature ne couvre que les en-têtes et qu'il n'y a aucune charge utile.

    Content-Encoding

    Définissez la valeur sur aws-chunked.

    Amazon S3 prend en charge plusieurs valeurs de codage de contenu. Vous pouvez spécifier votre codage de contenu personnalisé lorsque vous utilisez l'API de streaming Signature Version 4.

    Par exemple :

    Content-Encoding : aws-chunked,gzip

    Amazon S3 stocke l'objet obtenu sans la aws-chunked valeur figurant dans l'content-encodingen-tête. Si aws-chunked c'est la seule valeur que vous transmettez dans l'content-encodingen-tête, S3 considère que l'content-encodingen-tête est vide et ne renvoie pas cet en-tête lorsque vous récupérez l'objet.

    x-amz-decoded-content-length Définissez la valeur sur la longueur, en octets, des données à fractionner, sans compter les métadonnées. Par exemple, si vous chargez un fichier de 4 Go, définissez la valeur sur 4294967296. Il s'agit de la taille brute de l'objet à charger (données que vous souhaitez stocker dans Amazon S3).
    Content-Length

    Définissez la valeur sur la taille réelle du corps HTTP transmis, qui inclut la longueur de vos données (valeur définie pourx-amz-decoded-content-length), ainsi que les métadonnées des segments. Chaque bloc possède des métadonnées, telles que la signature du bloc précédent. Les calculs de blocs sont abordés dans la section suivante. Si vous incluez l'Transfer-Encodingen-tête et que vous spécifiez une valeur autre que identity celle-ci, vous ne devez pas inclure l'Content-Lengthen-tête.

Vous envoyez le premier bloc avec la signature de départ. Vous devez construire le bloc comme décrit dans la section suivante.

Définition du corps du morceau

Tous les segments incluent des métadonnées. Chaque morceau doit être conforme à la structure suivante :

string(IntHexBase(chunk-size)) + ";chunk-signature=" + signature + \r\n + chunk-data + \r\n

Où :

  • IntHexBase()est une fonction que vous écrivez pour convertir un entier de la taille d'un bloc en hexadécimal. Par exemple, si la taille du morceau est 65536, la chaîne hexadécimale est « 10000 ».

  • chunk-sizeest la taille, en octets, du bloc de données, sans les métadonnées. Par exemple, si vous chargez un objet de 65 Ko et que vous utilisez une taille de bloc de 64 Ko, vous chargez les données en trois blocs : le premier serait de 64 Ko, le second de 1 Ko et le dernier de 0 octet.

  • signaturePour chaque segment, vous calculez la signature à l'aide de la chaîne de caractères suivante. Pour le premier segment, vous utilisez la signature de départ comme signature précédente.

    Processus de calcul de la signature initiale montrant les différents composants de la chaîne à signer.

La taille du bloc final de données que vous envoyez est de 0, bien que le corps du bloc contienne toujours des métadonnées, y compris la signature du bloc précédent.

Exemple : objet PUT

Vous pouvez utiliser les exemples de cette section comme référence pour vérifier les calculs de signature dans votre code. Avant de passer en revue les exemples, prenez note des points suivants :

  • Les calculs de signature de ces exemples utilisent les informations d'identification de sécurité suivantes.

    Paramètre Value
    AWSAccessKeyId AKIAIOSFODNN7EXAMPLE
    AWSSecretAccessKey wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  • Tous les exemples utilisent l'horodatage de la requête 20130524T000000Z (). Fri, 24 May 2013 00:00:00 GMT

  • Tous les exemples sont utilisés examplebucket comme nom de compartiment.

  • Le compartiment est supposé se trouver dans la région de l'Est des États-Unis (Virginie du Nord), et les informations d'identification Scope et les Signing Key calculs sont utilisés us-east-1 comme spécificateur de région. Pour plus d'informations, consultez Régions et points de terminaison dans la Référence générale d'Amazon Web Services.

  • Vous pouvez utiliser des requêtes de style de chemin ou des requêtes de style hébergées virtuellement. Les exemples suivants utilisent des requêtes de style hébergées virtuellement, par exemple :

    https://examplebucket.s3.amazonaws.com/photos/photo1.jpg

    Pour plus d'informations, consultez la section Hébergement virtuel de compartiments dans le guide de l'utilisateur d'Amazon Simple Storage Service.

L'exemple suivant envoie une PUT demande pour télécharger un objet. Les calculs de signature supposent ce qui suit :

  • Vous chargez un fichier texte de 65 Ko dont le contenu est une chaîne d'un caractère composée de la lettre « a ».

  • La taille du bloc est de 64 Ko. Par conséquent, la charge utile est téléchargée en trois blocs, 64 Ko, 1 Ko, et le dernier bloc contenant 0 octet de données de bloc.

  • L'objet obtenu porte le nom de cléchunkObject.txt.

  • Vous faites une demande REDUCED_REDUNDANCY en tant que classe de stockage en ajoutant l'en-tête de x-amz-storage-class demande.

Pour plus d'informations sur l'action d'API, consultez PutObject. La syntaxe générale des requêtes est la suivante :

PUT /examplebucket/chunkObject.txt HTTP/1.1 Host: s3.amazonaws.com x-amz-date: 20130524T000000Z x-amz-storage-class: REDUCED_REDUNDANCY Authorization: SignatureToBeCalculated x-amz-content-sha256: STREAMING-AWS4-HMAC-SHA256-PAYLOAD Content-Encoding: aws-chunked x-amz-decoded-content-length: 66560 Content-Length: 66824 <Payload>

Les étapes suivantes présentent les calculs de signature.

  1. Signature d'origine — Créer une chaîne à signer
    1. CanonicalRequest

      PUT /examplebucket/chunkObject.txt content-encoding:aws-chunked content-length:66824 host:s3.amazonaws.com x-amz-content-sha256:STREAMING-AWS4-HMAC-SHA256-PAYLOAD x-amz-date:20130524T000000Z x-amz-decoded-content-length:66560 x-amz-storage-class:REDUCED_REDUNDANCY content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class STREAMING-AWS4-HMAC-SHA256-PAYLOAD

      Dans la requête canonique, la troisième ligne est vide car elle ne contient aucun paramètre de requête. La dernière ligne est la chaîne constante fournie comme valeur de la charge utile hachée, qui doit être identique à la valeur de. x-amz-content-sha256 header

    2. StringToSign

      AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request cee3fed04b70f867d036f722359b0b1f2f0e5dc0efadbc082b76c4c60e316455

      Note

      Pour plus d'informations sur chacune des lignes de la chaîne à signer, consultez le schéma qui explique le calcul de la signature initiale.

  2. SigningKey

    signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request")

  3. Signature de la graine

    4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9

  4. En-tête Authorization

    L'en-tête Authorization qui en résulte est le suivant :

    AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9

  5. Bloc 1 : (65536 octets, avec une valeur 97 pour la lettre « a »)
    1. Chaîne en morceaux à signer :

      AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request 4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 bf718b6f653bebc184e1479f1935b8da974d701b893afcf49e701f3e2f9f9c5a

      Note

      Pour plus d'informations sur chaque ligne de la chaîne à signer, consultez le schéma précédent qui montre les différents composants de la chaîne à signer (par exemple, les trois dernières lignes sont previous-signaturehash(""), ethash(current-chunk-data)).

    2. Signature du morceau :

      ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648
    3. Données partielles envoyées :

      10000;chunk-signature=ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 <65536-bytes>
  6. Bloc 2 : (1024 octets, avec une valeur 97 pour la lettre « a »)
    1. Chaîne en morceaux à signer :

      AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 2edc986847e209b4016e141a6dc8716d3207350f416969382d431539bf292e4a
    2. Signature du morceau :

      0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497
    3. Données partielles envoyées :

      400;chunk-signature=0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 <1024 bytes>
  7. Bloc 3 : (données de 0 octet)
    1. Chaîne en morceaux à signer :

      AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request 0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
    2. Signature du morceau :

      b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9
    3. Données partielles envoyées :

      0;chunk-signature=b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9