AWS S3 - ¿Cómo solucionar el error "La firma de solicitud que calculamos no coincide con la firma"?

89

He buscado en la web durante más de dos días y probablemente he revisado la mayoría de los escenarios y soluciones documentados en línea, pero nada me ha funcionado hasta ahora.

Estoy en AWS SDK para PHP V2.8.7 ejecutándose en PHP 5.3.

Estoy intentando conectarme a mi bucket de S3 con el siguiente código:

// 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();
        }
        //  

Mi archivo config.php es el siguiente:

<?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'
                )
            )
        )
    )
);

Está produciendo el siguiente error:

La firma de la solicitud que calculamos no coincide con la firma que proporcionó. Verifique su clave y método de firma.

Ya verifiqué mi clave de acceso y mi secreto al menos 20 veces, generé otras nuevas, usé diferentes métodos para pasar la información (es decir, el perfil y las credenciales incluidas en el código) pero nada funciona en este momento.

Joseph Lam
fuente
3
Entonces, AWS SDK simplemente implementa un montón de llamadas API directas. Con AWS, cada llamada que realiza toma su clave privada (o secretsuperior) y la usa para calcular una firma basada en su clave de acceso, la marca de tiempo actual, además de un montón de otros factores. Consulte docs.aws.amazon.com/general/latest/gr/… . Es una posibilidad remota, pero dado que incluyen la marca de tiempo, ¿quizás el tiempo de su entorno local está fuera de lugar?
Josh Padnick
Ocurrió cuando pasamos un tamaño incorrecto ( Content-Length) en los metadatos del objeto. (Versión larga: estábamos pasando directamente el flujo de entrada de un Java HttpServletRequestal cliente S3, y pasándolo request.getContentLength()como a Content-Lengthtravés de metadatos; cuando el servlet recibía (aleatoriamente) solicitudes fragmentadas ( Transfer-Encoding: chunked), getContentLength()regresaba -1, lo que provocó putObjectque fallara (aleatoriamente). Oscuro; pero claramente nuestra culpa porque estábamos pasando un tamaño de objeto incorrecto)
Janaka Bandara
Josh, el tiempo de mi computadora portátil tenía una hora de retraso (por alguna razón, estaba configurado en Moscú y no en Londres). ¡Gracias por la ayuda!
Ross Symonds

Respuestas:

79

Después de dos días de depuración, finalmente descubrí el problema ...

La clave que estaba asignando al objeto comenzó con un punto ..\images\ABC.jpg, es decir , y esto causó que ocurriera el error.

Deseo que la API proporcione un mensaje de error más significativo y relevante, por desgracia, ¡espero que esto ayude a alguien más!

Joseph Lam
fuente
Tenía el depósito de estado y la clave al revés y este es el error que obtiene (la firma no coincide). Wtf terraform?
Lo-Tan
14
Una barra inclinada también me causó este problema. Solo necesita ruta / a / archivo, no / ruta / a / archivo
Graham
3
Y para mí, el problema eran los espacios en blanco dentro de la clave
Adam Szmyd
3
Para agregar a esto, recibía este mensaje de error cuando tenía un signo más +en mi clave.
LCC
1
Recibí esto cuando no proporcioné el Content-Typeencabezado en mi solicitud de archivo de carga
Angel Venchev
33

Recibo este error con las credenciales incorrectas. Creo que había caracteres invisibles cuando lo pegué originalmente.

Alex Levine
fuente
3
Simplemente hice doble clic key_hash_lala/key_hash_continuesy seleccioné solo una parte. Por desgracia, ¿qué tan difícil es decirle al usuario "contraseña incorrecta, amigo"?
Ovnis
La primera vez que tuve problemas para copiar la clave del archivo csv descargable. Para la segunda clave que creé, la copié del navegador y no tuve ningún problema
nthaxis
+1 a @nthaxis - copiar desde el .csv causó un error - copiar directamente desde el navegador y funciona de
maravilla
13

Tuve el mismo problema cuando intenté copiar un objeto con algunos caracteres UTF8. A continuación se muestra un ejemplo de 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);

Resuelto codificando el CopySource con encodeURIComponent()

ecdesarrollador
fuente
9

Este error parece ocurrir principalmente si hay un espacio antes o después de su clave secreta

Harrish Selvarajah
fuente
esto es ayuda completa
Mr S Coder
Tenía el mismo problema. Skype a veces copia valores con líneas en blanco. Simplemente péguelo en el bloc de notas y luego cópielo sin espacios en blanco.
michal-michalak
Si ! Compruebe también si tiene espacios en otros encabezados.
Eino Gourdin
6

En realidad, en Java recibí el mismo error.Después de pasar 4 horas para depurarlo, encontré que el problema estaba en los metadatos en los objetos S3, ya que había espacio mientras se sentaban los controles de caché en los archivos s3.Este espacio estaba permitido en 1.6. * versión pero en 1.11. * no está permitida y, por lo tanto, arrojaba el error de discrepancia de firma

sarir
fuente
También sucede si pasa un error Content-Lengthen los metadatos
Janaka Bandara
3

Si ninguna de las otras soluciones mencionadas funciona para usted, intente usar

aws configure

este comando abrirá un conjunto de opciones solicitando claves, región y formato de salida.

¡Espero que esto ayude!

saurabh
fuente
3

Para mi usé axios y por sordo envía encabezado

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

así que cambio para enviar:

content-type: application/octet-stream

y también tuve que agregar este tipo de contenido a la firma de AWS

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

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

En una versión anterior de aws-php-sdk, antes de la desaprobación del S3Client::factory()método, se le permitía colocar parte de la ruta del archivo, o Keycomo se llama en los S3Client->putObject()parámetros , en el parámetro del depósito. Tenía un administrador de archivos en uso de producción, usando el SDK v2. Como el método de fábrica todavía funcionaba, no volví a visitar este módulo después de actualizar a ~3.70.0. Hoy pasé la mayor parte de las dos horas depurando por qué había comenzado a recibir este error, y terminó siendo debido a los parámetros que estaba pasando (que solían funcionar):

$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'
]);

Tuve que mover la catsinhatsparte de mi ruta de cubo / clave al Keyparámetro, así:

$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'
]);

Lo que creo que está pasando es que el Bucket nombre ahora está codificado en URL. Después de una inspección más profunda del mensaje exacto que recibía del SDK, encontré esto:

Error al ejecutar PutObjectelhttps://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.png

Error HTTP de AWS: Error del cliente: PUT https://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.pngresultó en un403 Forbidden

Esto muestra que el /que proporcioné a mi Bucketparámetro ha pasado urlencode()y está ahora %2F.

La forma en que funciona la firma es bastante complicada, pero el problema se reduce al depósito y la clave se utiliza para generar la firma cifrada. Si no coinciden exactamente tanto en el cliente que llama como en AWS, la solicitud se denegará con un 403. El mensaje de error en realidad señala el problema:

La firma de la solicitud que calculamos no coincide con la firma que proporcionó. Verifique su clave y método de firma.

Entonces, mi Keyestaba mal porque mi Bucketestaba mal.

Aaron St. Clair
fuente
3

Tuve el mismo error en nodejs. Pero agregar el signatureVersionconstructor s3 me ayudó:

const s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  signatureVersion: 'v4',
});
Oleg
fuente
¡Probé muchas cosas antes de tropezar con esto! Esta fue la respuesta para mí.
DavidG
2

Acabo de experimentar esto cargando una imagen en S3 usando AWS SDK con React Native. Resultó ser causado por elContentEncoding parámetro.

Eliminar ese parámetro "solucionó" el problema.

John Veldboom
fuente
2

Tuve el mismo problema. Tenía el método predeterminado, PUT configurado para definir la URL firmada previamente pero estaba tratando de realizar un GET. El error se debió a una falta de coincidencia de métodos.

maheeka
fuente
Esto funcionó para mí. El verbo HTTP (PUT, POST) que se usa para generar la URL firmada debe ser el mismo que el verbo que se usa al realizar una carga con esa URL.
craigcaulfield
2

En mi caso, estaba usando s3.getSignedUrl('getObject')cuando necesitaba usar s3.getSignedUrl('putObject')(porque estoy usando un PUT para cargar mi archivo), por lo que las firmas no coincidían.

Elon Zito
fuente
Me salvó después de largas horas. ¡¡Gracias!!
Kisinga
1

Tuve un error similar, pero para mí, parecía deberse a la reutilización de un usuario de IAM para trabajar con S3 en dos entornos Elastic Beanstalk diferentes. Traté el síntoma creando un usuario de IAM con permisos idénticos para cada entorno y eso hizo que el error desapareciera.

Joseph Combs
fuente
1

En mi caso, analicé una URL de S3 en sus componentes.

Por ejemplo:

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

Fue analizado en:

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

Tener la parte de la ruta que contiene un '/' inicial falló la solicitud.

AVIDeveloper
fuente
1

Otro posible problema podría ser que los valores meta contienen caracteres que no son US-ASCII. Para mí, ayudó a UrlEncode los valores al agregarlos a putRequest:

request.Metadata.Add(AmzMetaPrefix + "artist", HttpUtility.UrlEncode(song.Artist));
request.Metadata.Add(AmzMetaPrefix + "title", HttpUtility.UrlEncode(song.Title));
Sebastián
fuente
1

Resolví este problema cambiando los permisos públicos en mi bucket de AWS s3 y agregando la configuración CORS a continuación a la configuración de mi bucket.

<?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>

Consulte la documentación de AWS s3 para obtener más información.

LangostaBaz
fuente
1

La mayoría de las veces ocurre debido a la clave incorrecta (AWS_SECRET_ACCESS_KEY). Verifique su AWS_SECRET_ACCESS_KEY. Espero que funcione ...

Amol Kakade
fuente
1

Recibí este error al intentar copiar un objeto. Lo arreglé codificando el copySource. En realidad, esto se describe en la documentación del método:

Params: copySource: el nombre del depósito de origen y el nombre de la clave del objeto de origen, separados por una barra (/). Debe estar codificado en URL.

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

En mi caso, estaba usando S3 (mayúsculas) como nombre de servicio al realizar la solicitud usando cartero en el método de autorización de firma de AWS

judasane
fuente
¿Puede agregar más detalles sobre dónde anunciar AWS Sign?
Mr S Coder
1

Después de depurar y pasar mucho tiempo, en mi caso, el problema fue con access_key_id y secret_access_key, simplemente verifique sus credenciales o genere una nueva si es posible y asegúrese de que está pasando las credenciales en params.

jazeb007
fuente
Cuando leí la respuesta anterior, verifiqué mi clave secreta dos veces y me di cuenta de que había agregado / al final.
Ezrqn Kemboi
1

Para el conjunto de 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
fuente
En efecto. Más información aquí: aws.amazon.com/premiumsupport/knowledge-center/…
Davy
0

En mi caso, el nombre del depósito era incorrecto, incluía la primera parte de la clave (depósitoxxx / keyxxx); no había nada de malo en la firma.

Martin Flor
fuente
0

En mi caso (python) falló porque tenía estas dos líneas de código en el archivo, heredadas de un código anterior

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

Nir Soudry
fuente
0

Encontré esto en una imagen de Docker, con un punto final que no es de AWS S3, al usar la última awscliversión disponible para Debian stretch, es decir, la versión 1.11.13.

La actualización a la versión 1.16.84 de CLI resolvió el problema.

Para instalar la última versión de la CLI con un Dockerfile basado en una imagen extensible de Debian, en lugar de:

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

Utilizar:

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

Tuve que establecer

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

antes con ruby ​​aws sdk v2 (probablemente haya algo similar a esto en los otros idiomas también)

Yo Ludke
fuente
0

No sé si alguien llegó a este problema mientras intentaba probar la URL Postmangenerada en el navegador, pero si está utilizando e intenta copiar la URL generada de AWS desde la RAWpestaña, debido a las barras invertidas de escape, obtendrá el error anterior. .

Use la Prettypestaña para copiar y pegar la URL para ver si realmente funciona.

Me encontré con este problema recientemente y esta solución resolvió mi problema. Es con fines de prueba para ver si realmente recupera los datos a través de la URL.

Esta respuesta es una referencia para aquellos que intentan generar una descarga, un enlace temporal de AWS o, en general, generar una URL de AWS para usar.

pr1nc3
fuente
0

El problema en mi caso fue la URL de API Gateway utilizada para configurar Amplify que tenía una barra extra al final ...

La URL consultada parecía https://....amazonaws.com/myapi//myendpoint. Eliminé la barra extra en la configuración y funcionó.

No es el mensaje de error más explícito de mi vida.

7hibault
fuente
0

En mi caso estaba llamando s3request.promise().then() incorreclty, lo que provocó que dos ejecuciones de la solicitud sucedieran cuando solo se realizó una llamada.

Lo que quiero decir es que estaba iterando a través de 6 objetos, pero se hicieron 12 solicitudes (puede verificar iniciando sesión en la consola o depurando la red en el navegador)

Dado que la marca de tiempo de la segunda solicitud no deseada no coincidía con la firma de la primera, esto produjo este problema.

Mauricio Gracia Gutiérrez
fuente
0

Recibí este error al cargar el documento en CloudSearch a través del SDK de Java. El problema se debía a un carácter especial en el documento que se iba a cargar. El error "La firma de la solicitud que calculamos no coincide con la firma que proporcionó. Verifique su clave de acceso secreta de AWS y el método de firma". es muy engañoso.

parné
fuente
0

generar una clave de acceso nueva funcionó para mí.

yungBolo
fuente