AWS S3 - วิธีแก้ไขข้อผิดพลาด 'ลายเซ็นคำขอที่เราคำนวณไม่ตรงกับลายเซ็น'


95

ฉันค้นหาบนเว็บมานานกว่าสองวันแล้วและอาจได้ดูสถานการณ์และวิธีแก้ปัญหาที่มีเอกสารออนไลน์เกือบทั้งหมดแล้ว แต่ก็ยังไม่มีอะไรที่ใช้ได้ผลสำหรับฉันจนถึงตอนนี้

ฉันใช้AWS SDKสำหรับ PHP V2.8.7 ที่ทำงานบน PHP 5.3

ฉันกำลังพยายามเชื่อมต่อกับที่เก็บข้อมูล S3 ของฉันด้วยรหัสต่อไปนี้:

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

ไฟล์ config.php ของฉันเป็นดังนี้:

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

เกิดข้อผิดพลาดต่อไปนี้:

ลายเซ็นคำขอที่เราคำนวณไม่ตรงกับลายเซ็นที่คุณระบุ ตรวจสอบคีย์และวิธีการลงนาม

ฉันได้ตรวจสอบรหัสการเข้าถึงและรหัสลับของฉันแล้วอย่างน้อย 20 ครั้งสร้างขึ้นใหม่ใช้วิธีการต่างๆในการส่งผ่านข้อมูล (เช่นโปรไฟล์และข้อมูลประจำตัวในรหัส) แต่ไม่มีอะไรทำงาน


3
ดังนั้น AWS SDK จึงใช้การเรียก API โดยตรงจำนวนมาก ด้วย AWS ทุกครั้งที่คุณโทรจะใช้คีย์ส่วนตัวของคุณ (หรือsecretสูงกว่า) และใช้สิ่งนั้นเพื่อคำนวณลายเซ็นตามคีย์การเข้าถึงการประทับเวลาปัจจุบันและปัจจัยอื่น ๆ อีกมากมาย ดูdocs.aws.amazon.com/general/latest/gr/... มันเป็นช็อตช็อต แต่เนื่องจากมีการประทับเวลาด้วยบางทีเวลาของสภาพแวดล้อมในท้องถิ่นของคุณอาจจะหยุดทำงาน
Josh Padnick

เกิดขึ้นเมื่อเราส่งผ่านขนาดที่ไม่ถูกต้อง ( Content-Length) ในข้อมูลเมตาของวัตถุ (รุ่นยาว: เราได้โดยตรงผ่านสตรีมใส่จาก Java HttpServletRequestกับลูกค้า S3 และผ่านในrequest.getContentLength()ขณะที่Content-Lengthทางเมตาดาต้าเมื่อเซิร์ฟเล็ตเป็น (สุ่ม) ได้รับการร้องขอ chunked ( Transfer-Encoding: chunked) getContentLength()กำลังจะกลับ-1- ซึ่งนำไปสู่putObjectการล้มเหลว (สุ่ม) ปิดบัง แต่เห็นได้ชัดว่าความผิดของเราเป็นเพราะเราส่งขนาดวัตถุที่ไม่ถูกต้อง)
Janaka Bandara

Josh เวลาแล็ปท็อปของฉันคือหนึ่งชั่วโมง (ด้วยเหตุผลบางอย่างมันถูกตั้งค่าเป็นมอสโกวไม่ใช่เวลาลอนดอน) ขอบคุณสำหรับความช่วยเหลือ!
Ross Symonds

คำตอบ:


83

หลังจากสองวันของการดีบักในที่สุดฉันก็ค้นพบปัญหา ...

คีย์ที่ฉันกำหนดให้กับออบเจ็กต์เริ่มต้นด้วยจุดคือ..\images\ABC.jpgและสิ่งนี้ทำให้เกิดข้อผิดพลาด

ฉันหวังว่า API จะให้ข้อความแสดงข้อผิดพลาดที่มีความหมายและเกี่ยวข้องมากขึ้นอนิจจาฉันหวังว่านี่จะช่วยคนอื่นได้!


ฉันมีที่เก็บข้อมูลสถานะและคีย์ย้อนหลังและนี่คือข้อผิดพลาดที่คุณได้รับ (ลายเซ็นไม่ตรงกัน) Wtf Terraform?
Lo-Tan

17
เครื่องหมายทับนำก็ทำให้เกิดปัญหานี้สำหรับฉันเช่นกัน คุณต้องการแค่ path / to / file ไม่ใช่ / path / to / file
Graham

4
และสำหรับฉันปัญหาคือช่องว่างสีขาวภายในคีย์
Adam Szmyd

4
เพื่อเพิ่มสิ่งนี้ฉันได้รับข้อความแสดงข้อผิดพลาดนี้เมื่อมีเครื่องหมายบวก+ในคีย์ของฉัน
LCC

2
ฉันได้รับสิ่งนี้เมื่อฉันไม่ได้ระบุContent-Typeส่วนหัวในคำขอไฟล์อัปโหลด
Angel Venchev

37

ฉันได้รับข้อผิดพลาดนี้โดยมีข้อมูลรับรองไม่ถูกต้อง ฉันคิดว่ามีอักขระที่มองไม่เห็นเมื่อฉันวางมันในตอนแรก


3
ฉันเพียงแค่คลิก dobuble key_hash_lala/key_hash_continuesและมันเลือกเพียงส่วนเดียว อนิจจามันยากแค่ไหนที่จะบอกผู้ใช้ว่า "รหัสผ่านผิดเพื่อน!"
ยูเอฟโอ

ครั้งแรกที่ฉันมีปัญหาในการคัดลอกคีย์จาก csv ที่ดาวน์โหลดได้ สำหรับคีย์ที่สองที่ฉันสร้างขึ้นฉันเพิ่งคัดลอกมาจากเบราว์เซอร์และไม่มีปัญหาใด ๆ
nthaxis

+1 ถึง @nthaxis - การคัดลอกจาก. csv ทำให้เกิดความล้มเหลว - คัดลอกโดยตรงจากเบราว์เซอร์และทำงานได้ดี
NKCampbell

15

ฉันมีปัญหาเดียวกันเมื่อพยายามคัดลอกวัตถุที่มีอักขระ UTF8 บางตัว ด้านล่างนี้เป็นตัวอย่าง 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);

แก้ไขได้โดยการเข้ารหัส CopySource ด้วย encodeURIComponent()


11

ข้อผิดพลาดนี้ดูเหมือนจะเกิดขึ้นเป็นส่วนใหญ่หากมีช่องว่างก่อนหรือหลังคีย์ลับของคุณ


นี่คือความช่วยเหลืออย่างเต็มที่
Mr S Coder

มีปัญหาเดียวกัน บางครั้ง Skype จะคัดลอกค่าด้วยบรรทัดว่าง เพียงแค่วางลงในแผ่นจดบันทึกแล้วคัดลอกโดยไม่ต้องเว้นวรรค
michal-michalak

ครับ! ตรวจสอบด้วยว่าคุณมีช่องว่างในส่วนหัวอื่น ๆ หรือไม่
Eino Gourdin

6

จริงๆแล้วใน Java ฉันได้รับข้อผิดพลาดเดียวกันหลังจากใช้เวลา 4 ชั่วโมงในการดีบักสิ่งที่ฉันพบว่าปัญหาอยู่ในข้อมูลเมตาในวัตถุ S3 เนื่องจากมีพื้นที่ว่างขณะนั่งควบคุมแคชในไฟล์ s3 พื้นที่นี้ได้รับอนุญาตใน 1.6 * เวอร์ชัน แต่ใน 1.11. * ไม่ได้รับอนุญาตจึงทำให้เกิดข้อผิดพลาดในลายเซ็นที่ไม่ตรงกัน


นอกจากนี้ยังเกิดขึ้นหากคุณส่งContent-Lengthข้อมูลเมตาไม่ถูกต้อง
Janaka Bandara

4

สำหรับฉันฉันใช้ axios และโดยคนหูหนวกจะส่งส่วนหัว

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

ดังนั้นฉันจึงเปลี่ยนเป็นส่ง:

content-type: application/octet-stream

และยังต้องเพิ่ม Content-Type นี้ลงในลายเซ็น AWS

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

const s3 = new AWS.S3()
s3.getSignedUrl('putObject', params)

3

หากไม่มีวิธีแก้ไขปัญหาอื่นใดที่เหมาะกับคุณให้ลองใช้

aws configure

คำสั่งนี้จะเปิดชุดตัวเลือกเพื่อขอคีย์ภูมิภาคและรูปแบบเอาต์พุต

หวังว่านี่จะช่วยได้!


3

ในเวอร์ชันก่อนหน้าของ aws-php-sdk ก่อนที่จะเลิกใช้งานS3Client::factory()วิธีนี้คุณได้รับอนุญาตให้วางส่วนหนึ่งของเส้นทางไฟล์หรือKeyตามที่เรียกในS3Client->putObject()พารามิเตอร์บนพารามิเตอร์ที่เก็บข้อมูล ฉันมีตัวจัดการไฟล์ที่ใช้งานจริงโดยใช้ v2 SDK เนื่องจากวิธีการของโรงงานยังใช้งานได้ฉันจึงไม่ได้กลับไปที่โมดูลนี้อีกหลังจากอัปเดตเป็น~3.70.0. วันนี้ฉันใช้เวลาส่วนที่ดีกว่าของสองชั่วโมงในการดีบั๊กว่าทำไมฉันถึงเริ่มได้รับข้อผิดพลาดนี้และมันก็เกิดจากพารามิเตอร์ที่ฉันส่งผ่าน (ซึ่งเคยใช้งานได้):

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

ฉันต้องย้ายcatsinhatsส่วนของเส้นทางที่เก็บข้อมูล / คีย์ไปยังKeyพารามิเตอร์ดังนี้:

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

สิ่งที่ฉันเชื่อว่าเกิดขึ้นBucketคือตอนนี้ชื่อกำลังเข้ารหัส URL หลังจากตรวจสอบข้อความที่แน่นอนที่ฉันได้รับจาก SDK เพิ่มเติมแล้วฉันพบสิ่งนี้:

เกิดข้อผิดพลาดPutObjectในการดำเนินการhttps://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.png

ข้อผิดพลาด AWS HTTP: ข้อผิดพลาดไคลเอ็นต์: PUT https://s3.amazonaws.com/awesomecatpictures%2Fcatsinhats/whitecats/white_cat_in_hat1.pngส่งผลให้เกิดไฟล์403 Forbidden

นี้แสดงให้เห็นว่า/ผมมีให้กับฉันBucketพารามิเตอร์ได้รับการผ่านและขณะนี้urlencode()%2F

วิธีการทำงานของ Signature นั้นค่อนข้างซับซ้อน แต่ปัญหานี้เกิดขึ้นที่ที่เก็บข้อมูลและใช้คีย์เพื่อสร้างลายเซ็นที่เข้ารหัส หากไม่ตรงกันทุกประการทั้งในไคลเอนต์ที่โทรและภายใน AWS คำขอจะถูกปฏิเสธด้วย 403 ข้อความแสดงข้อผิดพลาดชี้ให้เห็นปัญหาจริง:

ลายเซ็นคำขอที่เราคำนวณไม่ตรงกับลายเซ็นที่คุณระบุ ตรวจสอบคีย์และวิธีการลงนาม

ดังนั้นฉันKeyผิดเพราะฉันBucketผิด


3

ฉันมีข้อผิดพลาดเดียวกันใน nodejs แต่การเพิ่มตัวsignatureVersionสร้าง s3 ช่วยฉัน:

const s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  signatureVersion: 'v4',
});

พยายามหลายสิ่งหลายอย่างก่อนที่ฉันจะสะดุดสิ่งนี้! นี่คือคำตอบสำหรับฉัน
DavidG

3

ในกรณีของฉันฉันใช้s3.getSignedUrl('getObject')เมื่อฉันจำเป็นต้องใช้s3.getSignedUrl('putObject')(เพราะฉันใช้ PUT เพื่ออัปโหลดไฟล์ของฉัน) ซึ่งเป็นสาเหตุที่ลายเซ็นไม่ตรงกัน


ช่วยฉันไว้หลังจากผ่านไปหลายชั่วโมง ขอขอบคุณ!!
Kisinga


2

ฉันเพิ่งพบสิ่งนี้ในการอัปโหลดภาพไปยัง S3 โดยใช้ AWS SDK พร้อม React Native ปรากฎว่าเกิดจากContentEncodingพารามิเตอร์

การลบพารามิเตอร์นั้น "แก้ไข" ปัญหา


2

ฉันมีปัญหาเดียวกัน ฉันมีวิธีการเริ่มต้น PUT ตั้งค่าเพื่อกำหนด URL ที่ลงนามล่วงหน้า แต่กำลังพยายามดำเนินการ GET ข้อผิดพลาดเกิดจากวิธีการไม่ตรงกัน


สิ่งนี้ได้ผลสำหรับฉัน คำกริยา HTTP (PUT, POST) ที่ใช้สร้าง URL ที่ลงนามต้องเป็นคำกริยาที่ใช้เมื่อทำการอัปโหลดด้วย URL นั้น
Craigcaulfield

1

ฉันมีข้อผิดพลาดที่คล้ายกัน แต่สำหรับฉันดูเหมือนว่าจะเกิดจากการใช้ผู้ใช้ IAM ซ้ำเพื่อทำงานกับ S3 ในสองสภาพแวดล้อม Elastic Beanstalk ที่แตกต่างกัน ฉันรักษาอาการโดยสร้างผู้ใช้ IAM ที่ได้รับอนุญาตเหมือนกันสำหรับแต่ละสภาพแวดล้อมและนั่นทำให้ข้อผิดพลาดหายไป


1

ในกรณีของฉันฉันแยกวิเคราะห์ S3 url เป็นส่วนประกอบ

ตัวอย่างเช่น:

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

ถูกแยกวิเคราะห์เป็น:

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

การมีส่วนพา ธ ที่มี "/" นำหน้าล้มเหลวในการร้องขอ


1

ปัญหาที่เป็นไปได้อีกประการหนึ่งอาจเกิดจากค่าเมตามีอักขระที่ไม่ใช่ US-ASCII สำหรับฉันมันช่วย UrlEncode ค่าเมื่อเพิ่มลงใน putRequest:

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

1

ฉันแก้ไขปัญหานี้โดยเปลี่ยนการอนุญาตสาธารณะในที่เก็บข้อมูล AWS s3 ของฉันและโดยการเพิ่มการกำหนดค่า CORS ร้องในการตั้งค่าที่เก็บข้อมูลของฉัน

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

ดูเอกสาร AWS s3สำหรับข้อมูลเพิ่มเติม


1

ส่วนใหญ่เกิดขึ้นเนื่องจากคีย์ผิด (AWS_SECRET_ACCESS_KEY) โปรดยืนยัน AWS_SECRET_ACCESS_KEY ของคุณ หวังว่ามันจะได้ผล ...


1

ฉันได้รับข้อผิดพลาดนี้ขณะพยายามคัดลอกวัตถุ ฉันแก้ไขโดยการเข้ารหัส copySource สิ่งนี้ได้อธิบายไว้ในเอกสารวิธีการ:

Params: copySource - ชื่อของที่เก็บข้อมูลต้นทางและชื่อคีย์ของวัตถุต้นทางคั่นด้วยเครื่องหมายทับ (/) ต้องเข้ารหัส URL

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

1

ในกรณีของฉันฉันใช้ S3 (ตัวพิมพ์ใหญ่) เป็นชื่อบริการเมื่อทำการร้องขอโดยใช้บุรุษไปรษณีย์ในวิธีการอนุญาตลายเซ็น AWS


คุณช่วยเพิ่มรายละเอียดเพิ่มเติมได้ไหมว่าจะโฆษณา AWS Sign ได้ที่ไหน
Mr S Coder

1

หลังจากแก้ไขข้อบกพร่องและใช้เวลานานมากในกรณีของฉันปัญหาคือ access_key_id และ secret_access_key เพียงตรวจสอบข้อมูลรับรองของคุณอีกครั้งหรือสร้างใหม่หากเป็นไปได้และตรวจสอบให้แน่ใจว่าคุณได้ส่งข้อมูลรับรองในรูปแบบพารามิเตอร์


เมื่อฉันอ่านคำตอบข้างต้นฉันตรวจสอบรหัสลับของฉันอีกครั้งและรู้ว่าฉันได้เพิ่ม / ในตอนท้าย
Ezrqn Kemboi


0

ในกรณีของฉัน (python) มันล้มเหลวเนื่องจากฉันมีโค้ดสองบรรทัดนี้ในไฟล์ซึ่งสืบทอดมาจากโค้ดที่เก่ากว่า

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


0

ฉันพบสิ่งนี้ในอิมเมจ Docker ที่มีปลายทางที่ไม่ใช่ AWS S3 เมื่อใช้awscliเวอร์ชันล่าสุดที่มีให้สำหรับ Debian stretch คือเวอร์ชัน 1.11.13

การอัปเกรดเป็น CLI เวอร์ชัน 1.16.84 สามารถแก้ไขปัญหาได้

ในการติดตั้ง CLI เวอร์ชันล่าสุดด้วย Dockerfile ที่ใช้อิมเมจแบบยืด Debian แทน:

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

ใช้:

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

0

ฉันต้องตั้งค่า

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

ก่อนหน้านี้กับ Ruby aws sdk v2 (อาจมีบางอย่างที่คล้ายกับสิ่งนี้ในภาษาอื่นด้วย)


0

ฉันไม่ทราบว่ามีใครพบปัญหานี้หรือไม่ขณะพยายามทดสอบ URL ที่ส่งออกในเบราว์เซอร์ แต่ถ้าคุณกำลังใช้Postmanและพยายามคัดลอก url ที่สร้างขึ้นของ AWS จากRAWแท็บเนื่องจากการหลีกเลี่ยงแบ็กสแลชคุณจะได้รับข้อผิดพลาดข้างต้น .

ใช้ Prettyแท็บเพื่อคัดลอกและวาง URL เพื่อดูว่าใช้งานได้จริงหรือไม่

ฉันพบปัญหานี้เมื่อเร็ว ๆ นี้และวิธีนี้ช่วยแก้ปัญหาของฉันได้ มีวัตถุประสงค์เพื่อทดสอบเพื่อดูว่าคุณดึงข้อมูลผ่าน url จริงหรือไม่

คำตอบนี้อ้างอิงถึงผู้ที่พยายามสร้างการดาวน์โหลดลิงก์ชั่วคราวจาก AWS หรือโดยทั่วไปจะสร้าง URL จาก AWS เพื่อใช้


0

ปัญหาในกรณีของฉันคือ URL เกตเวย์ API ที่ใช้ในการกำหนดค่า Amplify ที่มีเครื่องหมายทับพิเศษในตอนท้าย ...

url https://....amazonaws.com/myapi//myendpointที่สอบถามดูเหมือน ฉันลบเครื่องหมายทับพิเศษใน conf และใช้งานได้

ไม่ใช่ข้อความแสดงข้อผิดพลาดที่ชัดเจนที่สุดในชีวิตของฉัน


0

ในกรณีของฉันฉันโทร s3request.promise().then()ไม่สมบูรณ์ซึ่งทำให้เกิดการประหารชีวิตสองคำขอที่เกิดขึ้นเมื่อมีการโทรเพียงครั้งเดียว

สิ่งที่ฉันหมายถึงคือฉันทำซ้ำผ่านวัตถุ 6 รายการ แต่มีการร้องขอ 12 รายการ (คุณสามารถตรวจสอบได้โดยการเข้าสู่ระบบคอนโซลหรือเครือข่ายการดีบักในเบราว์เซอร์)

เนื่องจากการประทับเวลาสำหรับคำขอที่สองที่ไม่ต้องการไม่ตรงกับการจำลองของเฟิร์สจึงทำให้เกิดปัญหานี้


0

พบข้อผิดพลาดนี้ขณะอัปโหลดเอกสารไปยัง CloudSearch ผ่าน Java SDK ปัญหาเกิดจากอักขระพิเศษในเอกสารที่จะอัปโหลด ข้อผิดพลาด "ลายเซ็นคำขอที่เราคำนวณไม่ตรงกับลายเซ็นที่คุณให้ไว้ตรวจสอบ AWS Secret Access Key และวิธีการลงนาม" ทำให้เข้าใจผิดมาก


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.