AWS S3 - Comment corriger l'erreur "La signature de demande que nous avons calculée ne correspond pas à la signature"?

89

J'ai cherché sur le Web pendant plus de deux jours maintenant et j'ai probablement examiné la plupart des scénarios et solutions de contournement documentés en ligne, mais rien n'a fonctionné pour moi jusqu'à présent.

Je suis sur AWS SDK pour PHP V2.8.7 fonctionnant sur PHP 5.3.

J'essaie de me connecter à mon compartiment S3 avec le code suivant:

// Create a `Aws` object using a configuration file

        $aws = Aws::factory('config.php');

        // Get the client from the service locator by namespace
        $s3Client = $aws->get('s3');

        $bucket = "xxx";
        $keyname = "xxx";

        try {
            $result = $s3Client->putObject(array(
                'Bucket'        =>      $bucket,
                'Key'           =>      $keyname,
                'Body'          =>      'Hello World!'
            ));
            $file_error = false;
        } catch (Exception $e) {
            $file_error = true;
            echo $e->getMessage();
            die();
        }
        //  

Mon fichier config.php est le suivant:

<?php

return array(
    // Bootstrap the configuration file with AWS specific features
    'includes' => array('_aws'),
    'services' => array(
        // All AWS clients extend from 'default_settings'. Here we are
        // overriding 'default_settings' with our default credentials and
        // providing a default region setting.
        'default_settings' => array(
            'params' => array(
                'credentials' => array(
                    'key'    => 'key',
                    'secret' => 'secret'
                )
            )
        )
    )
);

Il produit l'erreur suivante:

La signature de demande que nous avons calculée ne correspond pas à la signature que vous avez fournie. Vérifiez votre clé et votre méthode de signature.

J'ai déjà vérifié ma clé d'accès et mon secret au moins 20 fois, j'en ai généré de nouvelles, j'ai utilisé différentes méthodes pour transmettre les informations (c'est-à-dire le profil et les informations d'identification dans le code) mais rien ne fonctionne pour le moment.

Joseph Lam
la source
3
Ainsi, le kit AWS SDK implémente simplement un tas d'appels d'API directs. Avec AWS, chaque appel que vous effectuez prend votre clé privée (ou secretsupérieure) et l'utilise pour calculer une signature en fonction de votre clé d'accès, de l'horodatage actuel, ainsi que de nombreux autres facteurs. Voir docs.aws.amazon.com/general/latest/gr/… . C'est long, mais étant donné qu'ils incluent l'horodatage, peut-être que l'heure de votre environnement local est désactivée?
Josh Padnick
Cela s'est produit lorsque nous avions passé une taille incorrecte ( Content-Length) dans les métadonnées d'objet. (Version longue: nous passions directement le flux d'entrée d'un Java HttpServletRequestau client S3, et passant request.getContentLength()comme Content-Lengthpar métadonnées, lorsque le servlet était ( au hasard) la réception des demandes chunked ( Transfer-Encoding: chunked), getContentLength()était de retour -1- ce qui a conduit putObjectà l' échec ( au hasard). Obscur; mais clairement de notre faute parce que nous passions une taille d'objet incorrecte.)
Janaka Bandara
Josh, l'heure de mon ordinateur portable était une heure de congé (pour une raison quelconque, elle était réglée sur Moscou et non sur l'heure de Londres). Merci pour l'aide!
Ross Symonds le

Réponses:

79

Après deux jours de débogage, j'ai enfin découvert le problème ...

La clé que j'attribuais à l'objet commençait par un point, c'est-à-dire ..\images\ABC.jpg, et cela provoquait l'erreur.

Je souhaite que l'API fournisse un message d'erreur plus significatif et pertinent, hélas, j'espère que cela aidera quelqu'un d'autre!

Joseph Lam
la source
J'ai eu le seau d'état et la clé à l'envers et c'est l'erreur que vous obtenez (la signature ne correspond pas). Wtf terraform?
Lo-Tan
14
Une barre oblique principale a également causé ce problème pour moi. Vous avez juste besoin de chemin / vers / fichier, pas de / chemin / vers / fichier
Graham
3
Et pour moi, le problème était les espaces blancs à l' intérieur de la clé
Adam Szmyd
3
Pour ajouter à cela, je recevais ce message d'erreur lorsque +j'avais un signe plus dans ma clé.
LCC
1
Content-Type
J'obtenais
33

J'obtiens cette erreur avec les mauvaises informations d'identification. Je pense qu'il y avait des personnages invisibles lorsque je l'ai collé à l'origine.

Alex Levine
la source
3
J'ai simplement cliqué dessus key_hash_lala/key_hash_continueset j'ai sélectionné une seule partie. Hélas, comment est-il difficile de dire à l'utilisateur "mauvais mot de passe, mec!"?
Ufos
La première fois, j'ai eu des problèmes pour copier la clé du csv téléchargeable. Pour la deuxième clé que j'ai créée, je viens de la copier à partir du navigateur et je n'ai eu aucun problème
nthaxis
+1 à @nthaxis - la copie à partir du .csv a causé un échec - la copie directement à partir du navigateur et cela fonctionne un régal
NKCampbell
13

J'ai eu le même problème en essayant de copier un objet avec des caractères UTF8. Voici un exemple JS:

var s3 = new AWS.S3();

s3.copyObject({
    Bucket: 'somebucket',
    CopySource: 'path/to/Weird_file_name_ðÓpíu.jpg',
    Key: 'destination/key.jpg',
    ACL: 'authenticated-read'
}, cb);

Résolu en encodant le CopySource avec encodeURIComponent()

développeur
la source
9

Cette erreur semble se produire principalement s'il y a un espace avant ou après votre clé secrète

Harrish Selvarajah
la source
c'est de l'aide complète
Mr S Coder
J'ai eu le même problème. Skype copie parfois les valeurs avec des lignes vides. Collez-le simplement dans le bloc-notes, puis copiez-le sans espaces.
michal-michalak
Oui ! Vérifiez également si vous avez des espaces dans les autres en-têtes.
Eino Gourdin
6

En fait, en Java, j'obtenais la même erreur.Après avoir passé 4 heures à le déboguer, j'ai trouvé que le problème était dans les métadonnées dans les objets S3 car il y avait de l'espace tout en restant assis les contrôles de cache dans les fichiers s3.Cet espace était autorisé dans 1.6. * version mais dans 1.11. * il est interdit et a donc généré l'erreur d'incompatibilité de signature

sarir
la source
Se produit également si vous passez une erreur Content-Lengthdans les métadonnées
Janaka Bandara
3

Si aucune des autres solutions mentionnées ne fonctionne pour vous, essayez d'utiliser

aws configure

cette commande ouvrira un ensemble d'options demandant les clés, la région et le format de sortie.

J'espère que cela t'aides!

saurabh
la source
3

Pour moi j'ai utilisé axios et par sourd il envoie en-tête

content-type: application/x-www-form-urlencoded

donc je change pour envoyer:

content-type: application/octet-stream

et a également dû ajouter ce type de contenu à la signature AWS

const params = {
    Bucket: bucket,
    Key: key,
    Expires: expires,
    ContentType = 'application/octet-stream'
}

const s3 = new AWS.S3()
s3.getSignedUrl('putObject', params)
Dawid K.
la source
3

Dans une version précédente de aws-php-sdk, avant la dépréciation de la S3Client::factory()méthode, vous étiez autorisé à placer une partie du chemin du fichier, ou Keycomme il est appelé dans les S3Client->putObject()paramètres , sur le paramètre bucket. J'avais un gestionnaire de fichiers en production, utilisant le SDK v2. Étant donné que la méthode d'usine fonctionnait toujours, je n'ai pas revisité ce module après la mise à jour vers ~3.70.0. Aujourd'hui, j'ai passé la majeure partie de deux heures à déboguer les raisons pour lesquelles j'avais commencé à recevoir cette erreur, et cela a fini par être dû aux paramètres que je passais (qui fonctionnaient auparavant):

$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
    'Bucket' => 'awesomecatpictures/catsinhats',
    'Key' => 'whitecats/white_cat_in_hat1.png',
    'SourceFile' => '/tmp/asdf1234'
]);

J'ai dû déplacer la catsinhatspartie de mon seau / chemin clé vers le Keyparamètre, comme ceci:

$s3Client = new S3Client([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2006-03-01'
]);
$result = $s3Client->putObject([
    'Bucket' => 'awesomecatpictures',
    'Key' => 'catsinhats/whitecats/white_cat_in_hat1.png',
    'SourceFile' => '/tmp/asdf1234'
]);

Ce que je crois se passe, c'est que Bucket nom est maintenant encodé en URL. Après une inspection plus approfondie du message exact que je recevais du SDK, j'ai trouvé ceci:

Erreur exécution PutObjectsurhttps://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.png

Erreur HTTP AWS: Erreur du client: a PUT https://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.pngentraîné un403 Forbidden

Cela montre que le que /j'ai fourni à mon Bucketparamètre a été traversé urlencode()et l'est maintenant %2F.

Le fonctionnement de la signature est assez compliqué, mais le problème se résume au compartiment et à la clé utilisée pour générer la signature cryptée. S'ils ne correspondent pas exactement à la fois sur le client appelant et dans AWS, la demande sera refusée avec un 403. Le message d'erreur indique en fait le problème:

La signature de demande que nous avons calculée ne correspond pas à la signature que vous avez fournie. Vérifiez votre clé et votre méthode de signature.

Donc, j'avais Keytort parce que j'avais Buckettort.

Aaron St. Clair
la source
3

J'ai eu la même erreur dans nodejs. Mais l'ajout signatureVersiondu constructeur s3 m'a aidé:

const s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  signatureVersion: 'v4',
});
Oleg
la source
J'ai essayé beaucoup de choses avant de tomber dessus! C'était la réponse pour moi.
DavidG il y a
2

Je viens de faire l'expérience du téléchargement d'une image sur S3 à l'aide du SDK AWS avec React Native. Il s'est avéré être causé par leContentEncoding paramètre.

La suppression de ce paramètre a "résolu" le problème.

John Veldboom
la source
2

J'ai eu le même problème. J'avais la méthode par défaut, PUT définie pour définir l'URL pré-signée, mais j'essayais d'effectuer un GET. L'erreur était due à une incompatibilité de méthode.

maheeka
la source
Cela a fonctionné pour moi. Le verbe HTTP (PUT, POST) utilisé pour générer l'URL signée doit être le même que le verbe utilisé lors d'un téléchargement avec cette URL.
craigcaulfield
2

Dans mon cas, j'utilisais s3.getSignedUrl('getObject')quand je devais utiliser s3.getSignedUrl('putObject')(parce que j'utilise un PUT pour télécharger mon fichier), c'est pourquoi les signatures ne correspondent pas.

Elon Zito
la source
M'a sauvé après de longues heures. Merci!!
Kisinga le
1

J'ai eu une erreur similaire, mais pour moi, cela semblait être dû à la réutilisation d'un utilisateur IAM pour travailler avec S3 dans deux environnements Elastic Beanstalk différents. J'ai traité le symptôme en créant un utilisateur IAM avec l'autorisation identique pour chaque environnement et cela a fait disparaître l'erreur.

Joseph Combs
la source
1

Dans mon cas, j'ai analysé une URL S3 dans ses composants.

Par exemple:

Url:    s3://bucket-name/path/to/file

A été analysé en:

Bucket: bucket-name
Path:   /path/to/file

Avoir la partie de chemin contenant un '/' de début a échoué la demande.

AVIDeveloper
la source
1

Un autre problème possible pourrait être que les valeurs méta contiennent des caractères non US-ASCII. Pour moi, cela m'a aidé à UrlEncode les valeurs lors de leur ajout à putRequest:

request.Metadata.Add(AmzMetaPrefix + "artist", HttpUtility.UrlEncode(song.Artist));
request.Metadata.Add(AmzMetaPrefix + "title", HttpUtility.UrlEncode(song.Title));
Sébastien
la source
1

J'ai résolu ce problème en modifiant les autorisations publiques sur mon compartiment AWS s3 et en ajoutant la configuration CORS ci-dessous à mes paramètres de compartiment.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration>
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Consultez la documentation AWS s3 pour plus d'informations.

HomardBaz
la source
1

La plupart du temps, cela se produit à cause d'une clé incorrecte (AWS_SECRET_ACCESS_KEY). Veuillez vérifier votre AWS_SECRET_ACCESS_KEY. J'espère que cela fonctionnera ...

Amol Kakade
la source
1

J'ai eu cette erreur en essayant de copier un objet. Je l'ai corrigé en encodant le copySource. Ceci est en fait décrit dans la documentation de la méthode:

Paramètres: copySource - Le nom du compartiment source et le nom de la clé de l'objet source, séparés par une barre oblique (/). Doit être encodé en URL.

CopyObjectRequest objectRequest = CopyObjectRequest.builder()
                .copySource(URLEncoder.encode(bucket + "/" + oldFileKey, "UTF-8"))
                .destinationBucket(bucket)
                .destinationKey(newFileKey)
                .build();
Diego Keller
la source
1

Dans mon cas, j'utilisais S3 (majuscules) comme nom de service lors de la demande à l'aide de postman dans la méthode d'autorisation de signature AWS

Judasane
la source
pouvez-vous s'il vous plaît ajouter plus de détails où publier AWS Sign?
Mr S Coder le
1

Après avoir débogué et passé beaucoup de temps, dans mon cas, le problème était lié à access_key_id et secret_access_key, vérifiez simplement vos informations d'identification ou générez-en une nouvelle si possible et assurez-vous de transmettre les informations d'identification dans les paramètres.

jazeb007
la source
Quand j'ai lu la réponse ci-dessus, j'ai revérifié ma clé secrète et réalisé que j'avais ajouté / à la fin.
Ezrqn Kemboi le
1

Pour l'ensemble Python - signature_version s3v4

s3 = boto3.client(
   's3',
   aws_access_key_id='AKIAIO5FODNN7EXAMPLE',
   aws_secret_access_key='ABCDEF+c2L7yXeGvUyrPgYsDnWRRC1AYEXAMPLE',
   config=Config(signature_version='s3v4')
)
saurav sarkar
la source
En effet. Plus d'informations ici: aws.amazon.com/premiumsupport/knowledge-center/…
Davy
0

Dans mon cas, le nom du bucket était faux, il incluait la première partie de la clé (bucketxxx / keyxxx) - il n'y avait rien de mal avec la signature.

Fleur de Martin
la source
0

Dans mon cas (python), cela a échoué car j'avais ces deux lignes de code dans le fichier, héritées d'un code plus ancien

http.client.HTTPConnection._http_vsn = 10 http.client.HTTPConnection._http_vsn_str = 'HTTP/1.0'

Nir Soudry
la source
0

J'ai rencontré cela dans une image Docker, avec un point de terminaison non AWS S3, lors de l'utilisation de la dernière awscli version disponible pour Debian Stretch, à savoir la version 1.11.13.

La mise à niveau vers la version 1.16.84 de la CLI a résolu le problème.

Pour installer la dernière version de la CLI avec un Dockerfile basé sur une image étirée Debian, au lieu de:

RUN apt-get update
RUN apt-get install -y awscli
RUN aws --version

Utilisation:

RUN apt-get update
RUN apt-get install -y python-pip
RUN pip install awscli
RUN aws --version
RWD
la source
0

Je devais régler

Aws.config.update({
  credentials: Aws::Credentials.new(access_key_id, secret_access_key)
})

avant avec le ruby ​​aws sdk v2 (il y a probablement quelque chose de similaire dans les autres langues également)

Yo Ludke
la source
0

Je ne sais pas si quelqu'un a rencontré ce problème en essayant de tester l'URL Postmanproduite dans le navigateur, mais si vous utilisez et essayez de copier l'URL générée d'AWS à partir de l' RAWonglet, en raison de l'échappement des contre-obliques, vous obtiendrez l'erreur ci-dessus .

Utilisez l' Prettyonglet pour copier et coller l'URL pour voir si cela fonctionne réellement.

J'ai rencontré ce problème récemment et cette solution a résolu mon problème. C'est à des fins de test pour voir si vous récupérez réellement les données via l'url.

Cette réponse est une référence à ceux qui essaient de générer un téléchargement, un lien temporaire à partir d'AWS ou généralement de générer une URL à partir d'AWS à utiliser.

pr1nc3
la source
0

Le problème dans mon cas était l'URL de la passerelle API utilisée pour configurer Amplify qui avait une barre oblique supplémentaire à la fin ...

L'URL demandée ressemblait à https://....amazonaws.com/myapi//myendpoint. J'ai supprimé la barre oblique supplémentaire dans la configuration et cela a fonctionné.

Pas le message d'erreur le plus explicite de ma vie.

7hibault
la source
0

Dans mon cas, j'appelais s3request.promise().then()incorreclty, ce qui provoquait deux exécutions de la demande lorsqu'un seul appel était effectué.

Ce que je veux dire, c'est que je parcourais 6 objets mais 12 demandes ont été faites (vous pouvez vérifier en vous connectant à la console ou en déboguant le réseau dans le navigateur)

Étant donné que l'horodatage de la deuxième demande indésirable ne correspondait pas à la signature de la première, ce problème a provoqué ce problème.

Mauricio Gracia Gutierrez
la source
0

Vous avez rencontré cette erreur lors du téléchargement du document vers CloudSearch via le SDK Java. Le problème était dû à un caractère spécial dans le document à télécharger. L'erreur "La signature de demande que nous avons calculée ne correspond pas à la signature que vous avez fournie. Vérifiez votre clé d'accès secrète AWS et votre méthode de signature." est très trompeur.

dibs
la source
0

générer une nouvelle clé d'accès a fonctionné pour moi.

yungBolo
la source