AWS S3 - Bagaimana cara memperbaiki kesalahan 'Tanda tangan permintaan yang kami hitung tidak cocok dengan tanda tangan'?

95

Saya telah mencari di web selama lebih dari dua hari sekarang, dan mungkin telah melihat sebagian besar skenario dan solusi yang didokumentasikan secara online, tetapi sejauh ini tidak ada yang berhasil untuk saya.

Saya menggunakan AWS SDK untuk PHP V2.8.7 yang berjalan di PHP 5.3.

Saya mencoba menghubungkan ke bucket S3 saya dengan kode berikut:

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

File config.php saya adalah sebagai berikut:

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

Ini menghasilkan kesalahan berikut:

Tanda tangan permintaan yang kami hitung tidak cocok dengan tanda tangan yang Anda berikan. Periksa kunci dan metode penandatanganan Anda.

Saya sudah memeriksa kunci akses dan rahasia saya setidaknya 20 kali, menghasilkan yang baru, menggunakan metode berbeda untuk menyampaikan informasi (yaitu profil dan memasukkan kredensial dalam kode) tetapi tidak ada yang berfungsi saat ini.

Joseph Lam
sumber
3
Jadi, AWS SDK hanya menerapkan banyak panggilan API langsung. Dengan AWS, setiap panggilan yang Anda lakukan mengambil kunci pribadi Anda (atau lebih secrettinggi), dan menggunakannya untuk menghitung tanda tangan berdasarkan kunci akses Anda, stempel waktu saat ini, ditambah banyak faktor lainnya. Lihat docs.aws.amazon.com/general/latest/gr/… . Ini adalah longshot, tetapi mengingat bahwa mereka menyertakan stempel waktu, mungkin waktu lingkungan lokal Anda tidak aktif?
Josh Padnick
Terjadi ketika kami mengirimkan ukuran yang salah ( Content-Length) dalam metadata objek. (Versi panjang: kami secara langsung meneruskan aliran input dari Java HttpServletRequestke klien S3, dan meneruskan request.getContentLength()sebagai Content-Lengthmelalui metadata; ketika servlet (secara acak) menerima permintaan potongan ( Transfer-Encoding: chunked), getContentLength()kembali -1- yang menyebabkan putObjectgagal (secara acak). Tidak jelas; tapi jelas kesalahan kami karena kami melewati ukuran objek yang salah.)
Janaka Bandara
Josh waktu laptop saya adalah satu jam off (untuk beberapa alasan itu diatur ke Moskow dan bukan waktu London). Terima kasih atas bantuannya!
Ross Symonds

Jawaban:

83

Setelah dua hari debugging, saya akhirnya menemukan masalahnya ...

Kunci yang saya tetapkan ke objek dimulai dengan periode yaitu ..\images\ABC.jpg, dan ini menyebabkan terjadinya kesalahan.

Saya berharap API memberikan pesan kesalahan yang lebih bermakna dan relevan, sayangnya, saya harap ini akan membantu orang lain di luar sana!

Joseph Lam
sumber
Saya memiliki ember negara dan kunci mundur dan ini adalah kesalahan yang Anda dapatkan (tanda tangan tidak cocok). Wtf terraform?
Lo-Tan
17
Sebuah garis miring juga menyebabkan masalah ini bagi saya. Anda hanya perlu jalur / ke / file, bukan / jalur / ke / file
Graham
4
Dan bagi saya masalahnya adalah ruang
kosong
4
Untuk menambah ini, saya mendapatkan pesan kesalahan ini ketika memiliki tanda plus +di kunci saya.
LCC
2
Saya mendapatkan ini ketika saya tidak memberikan Content-Typetajuk dalam permintaan file unggahan saya
Angel Venchev
37

Saya mendapatkan kesalahan ini dengan kredensial yang salah. Saya pikir ada karakter yang tidak terlihat ketika saya menempelkannya pada awalnya.

Alex Levine
sumber
3
Saya hanya mengklik dua kali key_hash_lala/key_hash_continuesdan memilih hanya satu bagian. Sayangnya, seberapa sulit memberi tahu pengguna "kata sandi salah, bung!"?
Ufos
Pertama kali saya mengalami masalah saat menyalin kunci dari csv yang dapat diunduh. Untuk kunci kedua yang saya buat, saya baru saja menyalinnya dari browser dan tidak memiliki masalah apa pun
nthaxis
+1 ke @nthaxis - menyalin dari .csv menyebabkan kegagalan - menyalin langsung dari browser dan berfungsi dengan baik
NKCampbell
15

Saya mengalami masalah yang sama ketika mencoba menyalin objek dengan beberapa karakter UTF8. Di bawah ini adalah contoh 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);

Dipecahkan dengan mengenkode CopySource dengan encodeURIComponent()

ecdeveloper
sumber
11

Kesalahan ini tampaknya terjadi terutama jika ada spasi sebelum atau sesudah kunci rahasia Anda

Harrish Selvarajah
sumber
ini membantu penuh
Mr S Coder
Punya masalah yang sama. Skype terkadang menyalin nilai dengan baris kosong. Cukup tempel ke notepad lalu salin tanpa spasi.
michal-michalak
Iya ! Periksa juga apakah Anda memiliki spasi di header lain.
Eino Gourdin
6

Sebenarnya di Java saya mendapatkan kesalahan yang sama. Setelah menghabiskan 4 jam untuk men-debug apa yang saya temukan bahwa masalahnya ada di meta data di Objek S3 karena ada ruang saat duduk kontrol cache di file s3. Ruang ini diizinkan di 1.6. * versi tetapi di 1.11. * itu tidak diizinkan dan dengan demikian melemparkan kesalahan ketidakcocokan tanda tangan

sarir
sumber
Juga terjadi jika Anda memberikan kesalahan Content-Lengthdalam metadata
Janaka Bandara
4

Bagi saya, saya menggunakan aksios dan dengan tuli mengirimkan header

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

jadi saya mengubah untuk mengirim:

content-type: application/octet-stream

dan juga harus menambahkan Jenis Konten ini ke tanda tangan AWS

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

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

Jika tidak ada solusi lain yang disebutkan berfungsi untuk Anda, coba gunakan

aws configure

perintah ini akan membuka serangkaian opsi yang menanyakan kunci, wilayah, dan format keluaran.

Semoga ini membantu!

saurabh
sumber
3

Dalam versi aws-php-sdk sebelumnya, sebelum metode dihentikan S3Client::factory(), Anda diizinkan untuk menempatkan bagian dari jalur file, atau Keyseperti yang disebut dalam S3Client->putObject()parameter , pada parameter bucket. Saya memiliki manajer file dalam penggunaan produksi, menggunakan v2 SDK. Karena metode pabrik masih berfungsi, saya tidak mengunjungi kembali modul ini setelah memperbarui ke ~3.70.0. Hari ini saya menghabiskan bagian yang lebih baik dari dua jam men-debug mengapa saya mulai menerima kesalahan ini, dan itu berakhir karena parameter yang saya lewati (yang dulu berfungsi):

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

Saya harus memindahkan catsinhatsporsi jalur bucket / key saya ke Keyparameter, seperti ini:

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

Apa yang saya yakini sedang terjadi adalah bahwa Bucketnama tersebut sekarang sedang dikodekan URL. Setelah pemeriksaan lebih lanjut tentang pesan persis yang saya terima dari SDK, saya menemukan ini:

Terjadi kesalahan saat menjalankan PutObjectpadahttps://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.png

Kesalahan HTTP AWS: Kesalahan klien: PUT https://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.pngmengakibatkan403 Forbidden

Ini menunjukkan bahwa /I berikan ke Bucketparameter saya telah melalui urlencode()dan sekarang %2F.

Cara kerja Tanda Tangan cukup rumit, tetapi masalahnya bermuara pada keranjang dan kunci digunakan untuk menghasilkan tanda tangan terenkripsi. Jika keduanya tidak sama persis pada klien pemanggil, dan di dalam AWS, maka permintaan akan ditolak dengan 403. Pesan kesalahan sebenarnya menunjukkan masalah:

Tanda tangan permintaan yang kami hitung tidak cocok dengan tanda tangan yang Anda berikan. Periksa kunci dan metode penandatanganan Anda.

Jadi, saya Keysalah karena saya Bucketsalah.

Aaron St. Clair
sumber
3

Saya mengalami kesalahan yang sama di nodejs. Tetapi menambahkan signatureVersionkonstruktor s3 membantu saya:

const s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  signatureVersion: 'v4',
});
Oleg
sumber
Mencoba banyak hal sebelum saya tersandung pada ini! Ini adalah jawaban untuk saya.
DavidG
3

Dalam kasus saya, saya menggunakan s3.getSignedUrl('getObject')ketika saya perlu menggunakan s3.getSignedUrl('putObject')(karena saya menggunakan PUT untuk mengunggah file saya), itulah sebabnya tanda tangannya tidak cocok.

Elon Zito
sumber
Menyelamatkan saya setelah berjam-jam. Terima kasih!!
Kisinga
3

Untuk set 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
sumber
Memang. Info lebih lanjut di sini: aws.amazon.com/premiumsupport/knowledge-center/…
Davy
2

Saya baru saja mengalami ini mengunggah gambar ke S3 menggunakan AWS SDK dengan React Native. Ternyata itu disebabkan olehContentEncoding parameter.

Menghapus parameter itu "memperbaiki" masalah.

John Veldboom
sumber
2

Saya memiliki masalah yang sama. Saya memiliki metode default, PUT diatur untuk menentukan URL yang telah ditandatangani sebelumnya tetapi mencoba melakukan GET. Kesalahan ini terjadi karena ketidakcocokan metode.

maheeka
sumber
Ini berhasil untuk saya. Kata kerja HTTP (PUT, POST) yang digunakan untuk menghasilkan URL bertanda tangan harus sama dengan kata kerja yang digunakan saat melakukan unggahan dengan URL tersebut.
craigcaulfield
1

Saya mengalami kesalahan yang serupa, tetapi bagi saya tampaknya itu disebabkan oleh penggunaan kembali pengguna IAM untuk bekerja dengan S3 di dua lingkungan Elastic Beanstalk yang berbeda. Saya menangani gejala tersebut dengan membuat pengguna IAM dengan izin yang sama untuk setiap lingkungan dan itu membuat kesalahan hilang.

Joseph Combs
sumber
1

Dalam kasus saya, saya mengurai url S3 ke dalam komponennya.

Sebagai contoh:

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

Diurai menjadi:

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

Memiliki bagian jalur yang berisi awalan '/' gagal dalam permintaan.

AVIDeveloper
sumber
1

Masalah lain yang mungkin mungkin terjadi karena nilai meta mengandung karakter non US-ASCII. Bagi saya, ini membantu UrlEncode nilai saat menambahkannya ke putRequest:

request.Metadata.Add(AmzMetaPrefix + "artist", HttpUtility.UrlEncode(song.Artist));
request.Metadata.Add(AmzMetaPrefix + "title", HttpUtility.UrlEncode(song.Title));
Sebastian
sumber
1

Saya menyelesaikan masalah ini dengan mengubah izin publik pada bucket AWS s3 saya dan dengan menambahkan konfigurasi CORS di bawah ke pengaturan bucket saya.

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

Lihat dokumentasi AWS s3 untuk info lebih lanjut.

LobsterBaz
sumber
1

Sering kali ini terjadi karena kunci yang salah (AWS_SECRET_ACCESS_KEY). Harap verifikasi silang AWS_SECRET_ACCESS_KEY Anda. Semoga berhasil ...

Amol Kakade
sumber
1

Saya mendapat kesalahan ini saat mencoba menyalin objek. Saya memperbaikinya dengan mengenkode copySource. Ini sebenarnya dijelaskan dalam dokumentasi metode:

Params: copySource - Nama bucket sumber dan nama kunci objek sumber, dipisahkan dengan garis miring (/). Harus dienkode URL.

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

Dalam kasus saya, saya menggunakan S3 (huruf besar) sebagai nama layanan saat membuat permintaan menggunakan tukang pos dalam metode Otorisasi tanda tangan AWS

judasane
sumber
Bisakah Anda menambahkan lebih detail di mana harus memasang iklan AWS Sign?
Mr S Coder
1

Setelah men-debug dan menghabiskan banyak waktu, dalam kasus saya, masalahnya adalah dengan access_key_id dan secret_access_key, cukup periksa kembali kredensial Anda atau buat yang baru jika memungkinkan dan pastikan Anda meneruskan kredensial di params.

jazeb007.dll
sumber
Ketika saya membaca jawaban di atas, saya memeriksa ulang kunci rahasia saya dan menyadari bahwa saya telah menambahkan / di akhir.
Ezrqn Kemboi
0

Dalam kasus saya, nama bucket salah, itu termasuk bagian pertama dari kunci (bucketxxx / keyxxx) - tidak ada yang salah dengan tanda tangannya.

Bunga Martin
sumber
0

Dalam kasus saya (python) gagal karena saya memiliki dua baris kode ini di file, diwarisi dari kode yang lebih lama

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

Nir Soudry
sumber
0

Saya menemukan ini dalam gambar Docker, dengan titik akhir S3 non-AWS, saat menggunakan awscliversi terbaru yang tersedia untuk peregangan Debian, yaitu versi 1.11.13.

Mengupgrade ke CLI versi 1.16.84 menyelesaikan masalah.

Untuk menginstal CLI versi terbaru dengan Dockerfile berdasarkan image regangan Debian, alih-alih:

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

Menggunakan:

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

Saya harus mengatur

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

sebelumnya dengan ruby ​​aws sdk v2 (mungkin ada yang mirip dengan ini di bahasa lain juga)

Yo Ludke
sumber
0

Saya tidak tahu apakah ada yang datang ke masalah ini saat mencoba menguji URL yang dikeluarkan di browser tetapi jika Anda menggunakan Postmandan mencoba menyalin url yang dihasilkan dari AWS dari RAWtab, karena keluar dari garis miring terbalik Anda akan mendapatkan kesalahan di atas .

Gunakan Prettytab untuk menyalin dan menempel url untuk melihat apakah itu benar-benar berfungsi.

Saya mengalami masalah ini baru-baru ini dan solusi ini menyelesaikan masalah saya. Ini untuk tujuan pengujian untuk melihat apakah Anda benar-benar mengambil data melalui url.

Jawaban ini adalah referensi bagi mereka yang mencoba menghasilkan unduhan, tautan sementara dari AWS atau secara umum membuat URL dari AWS untuk digunakan.

pr1nc3
sumber
0

Masalah dalam kasus saya adalah URL API Gateway yang digunakan untuk mengonfigurasi Amplify yang memiliki garis miring ekstra di bagian akhir ...

Url yang ditanyakan tampak seperti https://....amazonaws.com/myapi//myendpoint. Saya menghapus garis miring ekstra di conf dan berhasil.

Bukan pesan kesalahan paling eksplisit dalam hidup saya.

7hibault
sumber
0

Dalam kasus saya, saya menelepon s3request.promise().then()tidak akurat yang menyebabkan dua eksekusi permintaan terjadi ketika hanya satu panggilan dilakukan.

Yang saya maksud adalah bahwa saya melakukan iterasi melalui 6 objek tetapi 12 permintaan dibuat (Anda dapat memeriksa dengan masuk ke konsol atau jaringan debug di browser)

Karena stempel waktu untuk permintaan kedua, yang tidak diinginkan, tidak cocok dengan tanda pertama yang menghasilkan masalah ini.

Mauricio Gracia Gutierrez
sumber
0

Dapatkan kesalahan ini saat mengupload dokumen ke CloudSearch melalui Java SDK. Masalahnya karena karakter khusus dalam dokumen yang akan diunggah. Kesalahan "Tanda tangan permintaan yang kami hitung tidak cocok dengan tanda tangan yang Anda berikan. Periksa Kunci Akses Rahasia AWS dan metode penandatanganan." sangat menyesatkan.

dibs
sumber
0

membuat kunci akses baru berhasil untuk saya.

yungBolo
sumber