Di Object Storage Service (OSS), metode verifikasi identitas yang paling umum adalah menyertakan signature dalam header Authorization pada permintaan HTTP. Kecuali untuk signature POST dan URL, semua operasi OSS harus diautentikasi menggunakan header Authorization. Topik ini menjelaskan cara menggunakan algoritma signature V1 untuk menyertakan signature dalam header.
OSS mendukung algoritma signature V4 yang menawarkan keamanan lebih baik. Kami menyarankan Anda menggunakan signature V4. Untuk informasi selengkapnya, lihat V4 signature.
Implementasi signature SDK
OSS SDK secara otomatis menangani signature V1. Anda tidak perlu menghitung signature secara manual saat menggunakan SDK. Untuk memahami implementasinya dalam bahasa pemrograman tertentu, Anda dapat melihat kode sumber SDK tersebut. Tabel berikut mencantumkan file implementasi signature untuk setiap SDK.
|
SDK |
Implementasi Tanda Tangan |
|
Java |
|
|
PHP |
|
|
Node.js |
|
|
Browser.js |
|
|
Python |
|
|
.Net |
|
|
Android |
|
|
Go |
|
|
iOS |
|
|
C++ |
|
|
C |
|
|
Ruby |
Cara menghitung bidang Authorization
Metode perhitungan
Authorization = "OSS " + AccessKeyId + ":" + Signature
Signature = base64(hmac-sha1(AccessKeySecret,
VERB + "\n"
+ Content-MD5 + "\n"
+ Content-Type + "\n"
+ Date + "\n"
+ CanonicalizedOSSHeaders
+ CanonicalizedResource))
Parameter
|
Parameter |
Tipe |
Wajib |
Contoh |
Deskripsi |
|
AccessKeyId |
String |
Ya |
LTAI******************** |
Pasangan AccessKey Anda, yang terdiri dari ID AccessKey dan Rahasia AccessKey.
|
|
AccessKeySecret |
String |
Ya |
yourAccessKeySecret |
|
|
x-oss-security-token |
String |
Tidak |
CAIS******************************** |
Token Security Token Service (STS). Parameter ini hanya diperlukan ketika Anda menggunakan STS untuk membuat signature dalam header. Untuk informasi selengkapnya tentang cara mendapatkan token keamanan, lihat AssumeRole. |
|
VERB |
Enumeration |
Ya |
PUT |
Metode permintaan HTTP, seperti PUT, GET, POST, HEAD, DELETE, atau OPTIONS. |
|
\n |
String |
Tidak |
\n |
Karakter line feed. |
|
Content-MD5 |
String |
Tidak |
eB5e******************** |
Hash MD5 dari badan permintaan. Untuk menghitung nilai ini, hitung hash MD5 128-bit dari badan pesan (tidak termasuk header), lalu encode hasilnya dengan Base64. Untuk informasi selengkapnya, lihat RFC2616 Content-MD5. Header permintaan ini dapat digunakan untuk memeriksa integritas pesan. Pesan dianggap valid jika konten yang diterima sama dengan konten yang dikirim. Parameter ini boleh kosong. Untuk informasi selengkapnya tentang cara menghitung nilai Content-MD5, lihat Cara menghitung Content-MD5. |
|
Content-Type |
String |
Tidak |
application/octet-stream |
Jenis konten permintaan. Parameter ini boleh kosong. Catatan
Jika Anda tidak mengatur Content-Type saat membuat signature, Anda tidak perlu mengatur parameter ini saat menggunakan signature tersebut untuk mengunggah file. |
|
Date |
String |
Ya |
Sun, 22 Nov 2015 08:16:38 GMT |
Waktu operasi. Nilainya harus dalam format GMT dan tidak boleh kosong. Nilai diambil dari bidang Date atau x-oss-date dalam header permintaan. Jika kedua bidang tersebut ada, x-oss-date memiliki prioritas lebih tinggi. Penting
Jika waktu yang ditentukan dalam header Date permintaan berbeda lebih dari 15 menit dari waktu server OSS, OSS akan menolak permintaan tersebut dan mengembalikan error HTTP 403. |
|
CanonicalizedOSSHeaders |
String |
Tidak |
x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n |
Header HTTP yang diawali dengan
Untuk informasi selengkapnya tentang cara membuat string ini, lihat Cara membuat CanonicalizedOSSHeaders. |
|
CanonicalizedResource |
String |
Ya |
examplebucket |
Sumber daya OSS yang ingin Anda akses. String ini tidak boleh kosong. Untuk informasi selengkapnya tentang cara membuat string ini, lihat Cara membuat CanonicalizedResource. |
Contoh signature
-
Contoh 1 (menyertakan semua parameter)
Permintaan
Rumus string yang akan ditandatangani
String yang akan ditandatangani
PUT /nelson HTTP/1.0 Content-MD5: eB5e******************** Content-Type: text/html Date: Wed, 28 Dec 2022 10:27:41 GMT Host: examplebucket.oss-cn-hangzhou.aliyuncs.com x-oss-meta-author: alice x-oss-meta-magic: abracadabra
Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource))
PUT\n eB5e********************\n text/html\n Wed, 28 Dec 2022 10:27:41 GMT\n x-oss-meta-magic:abracadabra\nx-oss-meta-author:alice\n/examplebucket/nelson
Jika ID AccessKey adalah LTAI**************** dan Rahasia AccessKey adalah yourAccessKeySecret, Anda dapat menggunakan kode Python berikut untuk menghitung signature.
import hmac import hashlib import base64 h = hmac.new("yourAccessKeySecret".encode('utf-8'), "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM\ntext/html\nWed, 28 Dec 2022 10:27:41 GMT\nx-oss-meta-magic:abracadabra\nx-oss-meta-author:alice\n/oss-example/nelson".encode('utf-8'), hashlib.sha1) signature = base64.encodebytes(h.digest()) print(signature)Signature yang dihitung adalah
J9Nl************************. Permintaan akhir disusun sebagai berikut.PUT /nelson HTTP/1.0 Authorization:OSS LTAI****************:J9Nl************************ Content-Md5: eB5e******************** Content-Type: text/html Date: Wed, 28 Dec 2022 10:27:41 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com x-oss-meta-author: alice x-oss-meta-magic: abracadabra -
Contoh 2 (tidak menyertakan parameter opsional Content-MD5 dan Content-Type)
Permintaan
Rumus string yang akan ditandatangani
String yang akan ditandatangani
PUT /nelson HTTP/1.0 Date: Wed, 28 Dec 2022 09:56:32 GMT Host: examplebucket.oss-cn-hangzhou.aliyuncs.com x-oss-meta-author: alice x-oss-meta-magic: abracadabra
Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + "\n" + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource))
PUT\n\n\nWed, 28 Dec 2022 09:56:32 GMT\n x-oss-meta-magic:abracadabra\nx-oss-meta-author:alice\n/examplebucket/nelson
Pada contoh ini, ID AccessKey adalah LTAI**************** dan Rahasia AccessKey adalah yourAccessKeySecret. Kode Python berikut menunjukkan cara menghitung signature.
import hmac import hashlib import base64 h = hmac.new("yourAccessKeySecret".encode('utf-8'), "PUT\n\n\nWed, 28 Dec 2022 09:56:32 GMT\nx-oss-meta-magic:abracadabra\nx-oss-meta-author:alice\n/oss-example/nelson".encode('utf-8'), hashlib.sha1) signature = base64.encodebytes(h.digest()) print(signature)Signature yang dihitung adalah
Mhb1************************. Permintaan akhir disusun sebagai berikut.PUT /nelson HTTP/1.0 Authorization:OSS LTAI****************:Mhb1************************ Date: Wed, 28 Dec 2022 09:56:32 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com x-oss-meta-author: alice x-oss-meta-magic: abracadabra
Informasi tambahan
-
Jika ID AccessKey yang diberikan tidak ada atau tidak aktif, OSS mengembalikan error 403 Forbidden dengan kode kesalahan InvalidAccessKeyId. Jika ID AccessKey aktif tetapi OSS mendeteksi kesalahan signature dalam permintaan, OSS mengembalikan error 403 Forbidden. Respons mencakup string yang benar untuk ditandatangani, yang dapat Anda gunakan untuk memverifikasi proses penandatanganan Anda.
Kode berikut menunjukkan contoh respons:
<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B**** </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.*** </HostId> <SignatureProvided> y5H7************************ </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /examplebucket?acl </StringToSign> <OSSAccessKeyId> AKIA**************** </OSSAccessKeyId> </Error> -
Jika format nilai Authorization dalam header permintaan salah, OSS mengembalikan error 400 Bad Request dengan kode kesalahan InvalidArgument.
-
Semua permintaan yang dikirim ke OSS harus menggunakan format tanggal GMT yang ditentukan dalam HTTP 1.1. Format tanggalnya adalah sebagai berikut:
date1 = 2DIGIT SP month SP 4DIGIT; day month year (misalnya, 02 Jun 1982)CatatanDalam format tanggal di atas,
dayadalah angka dua digit. Oleh karena itu,Jun 2,2 Jun 1982, dan2-Jun-1982semuanya merupakan format tanggal yang tidak valid.-
Jika header Date tidak ada dalam permintaan yang ditandatangani atau dalam format yang tidak valid, OSS mengembalikan error 403 Forbidden dengan kode kesalahan AccessDenied.
-
Waktu dalam permintaan harus berada dalam rentang 15 menit dari waktu server OSS saat ini. Jika tidak, OSS mengembalikan error 403 Forbidden dengan kode kesalahan RequestTimeTooSkewed.
-
Cara membuat CanonicalizedOSSHeaders
Semua header HTTP yang diawali dengan x-oss- dikenal sebagai header OSS canonicalized. Untuk membuat string CanonicalizedOSSHeaders, ikuti langkah-langkah berikut:
-
Ubah nama semua header permintaan HTTP yang diawali dengan
x-oss-menjadi huruf kecil. Misalnya, ubahX-OSS-Meta-Name: TaoBaomenjadix-oss-meta-name: TaoBao. -
Jika Anda mengirim permintaan menggunakan kredensial akses sementara dari Security Token Service (STS), Anda harus menambahkan token keamanan ke string yang akan ditandatangani dalam format
x-oss-security-token:security-token.CatatanUntuk informasi selengkapnya tentang cara mengonfigurasi STS, lihat Gunakan kredensial sementara yang disediakan oleh STS untuk mengakses OSS. Anda dapat memanggil operasi AssumeRole atau menggunakan STS SDK untuk berbagai bahasa pemrograman untuk mendapatkan kredensial akses sementara. Kredensial akses sementara berisi token keamanan dan pasangan AccessKey sementara. Pasangan AccessKey terdiri dari ID AccessKey dan Rahasia AccessKey.
-
Urutkan semua header permintaan HTTP yang diperoleh secara leksikografis berdasarkan nama header.
-
Hapus spasi di kedua sisi tanda titik dua yang memisahkan nama header dan nilainya. Misalnya, ubah
x-oss-meta-name: TaoBaomenjadix-oss-meta-name:TaoBao. -
Gabungkan header yang telah diproses. Pisahkan setiap header dengan karakter line feed (
\n) untuk membuat string CanonicalizedOSSHeaders.
Cara membuat CanonicalizedResource
Sumber daya OSS target yang ingin Anda akses dalam permintaan dikenal sebagai resource canonicalized. Untuk membuat string CanonicalizedResource, ikuti aturan berikut:
-
Jika resource mencakup bucket dan objek, atur CanonicalizedResource menjadi /BucketName/ObjectName.
-
Jika resource hanya mencakup bucket, atur CanonicalizedResource menjadi /BucketName/.
-
Jika resource tidak mencakup bucket atau objek, atur CanonicalizedResource menjadi garis miring maju (/).
-
Jika permintaan mencakup subresource, urutkan semua subresource secara leksikografis dan gabungkan dengan tanda ampersand (
&) untuk membuat string subresource. Tambahkan tanda tanya (?) dan string subresource ke akhir string CanonicalizedResource. Hasil string CanonicalizedResource berada dalam format/BucketName/ObjectName?acl&uploadId=UploadId.OSS mendukung empat jenis subresource berikut:
-
Identifier resource, seperti acl, uploads, location, cors, logging, website, referer, lifecycle, delete, append, tagging, objectMeta, uploadId, partNumber, security-token, position, img, style, styleName, replication, replicationProgress, replicationLocation, cname, bucketInfo, comp, qos, live, status, vod, startTime, endTime, symlink, x-oss-process, callback, dan callback-var. Untuk informasi selengkapnya, lihat Operasi bucket dan Operasi objek.
PentingIdentifier resource bersifat case-sensitive.
-
Bidang header respons, seperti response-content-language, response-expires, response-cache-control, response-content-disposition, dan response-content-encoding. Untuk informasi selengkapnya, lihat GetObject.
-
Metode pemrosesan gambar, seperti
x-oss-process. Untuk informasi selengkapnya, lihat Pemrosesan gambar. -
Bidang kontrol akses yang diawali dengan
x-oss-ac-*, seperti x-oss-ac-source-ip, x-oss-ac-subnet-mask, x-oss-ac-vpc-id, dan x-oss-ac-forward-allow. Untuk informasi selengkapnya, lihat Signature version 1.CatatanSetelah Anda membuat signature menggunakan string CanonicalizedResource yang berisi parameter x-oss-ac-source-ip, hapus x-oss-ac-source-ip dari parameter kueri permintaan untuk melindungi alamat IP.
-
Aturan perhitungan signature
-
String yang akan ditandatangani harus dalam format
UTF-8. String yang berisi karakter Cina harus terlebih dahulu diencode dalamUTF-8sebelum digunakan denganAccessKeySecretuntuk menghitung signature. -
Signature dihitung menggunakan metode HMAC-SHA1 sebagaimana didefinisikan dalam RFC 2104. Kunci untuk perhitungan tersebut adalah Rahasia AccessKey Anda.
-
Content-TypedanContent-MD5tidak wajib dalam permintaan. Jika header-header ini tidak ada dalam permintaan yang memerlukan verifikasi signature, Anda tetap harus menyertakan karakter line feed (\n) untuk masing-masing dalam string yang akan ditandatangani. -
Hanya header HTTP non-standar yang diawali dengan
x-oss-yang harus disertakan dalam string yang akan ditandatangani. Misalnya, header x-oss-meta-magic dalam contoh signature harus disertakan. Header HTTP non-standar lainnya diabaikan oleh OSS.CatatanHeader yang diawali dengan
x-oss-harus diproses sesuai aturan berikut sebelum verifikasi signature:-
Nama header harus dalam huruf kecil.
-
Header harus diurutkan secara leksikografis berdasarkan nama.
-
Tidak boleh ada spasi sebelum atau sesudah tanda titik dua yang memisahkan nama header dan nilainya.
-
Setiap header harus dipisahkan oleh karakter line feed (\n). Jika tidak ada header semacam itu, string CanonicalizedOSSHeaders kosong.
-
Cara menghitung Content-MD5
Bagian ini menggunakan konten pesan "0123456789" sebagai contoh untuk menunjukkan cara yang benar dan salah dalam menghitung nilai Content-MD5.
-
Perhitungan yang benar
-
Pertama, hitung hash MD5, yang merupakan array biner 128-bit.
-
Encode array biner tersebut dengan Base64, bukan string heksadesimal 32 karakter.
Contoh berikut menggunakan Python:
>>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") # Di Python 3, ubah menjadi hash.update(b"0123456789"). >>> base64.b64encode(hash.digest()) 'eB5e********************'Metode hash.digest() mengembalikan array biner 128-bit.
>>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' -
-
Contoh perhitungan yang salah
CatatanKesalahan umum adalah langsung mengencode string heksadesimal 32 karakter dengan Base64.
# Metode hash.hexdigest() menghitung string heksadesimal 32 karakter yang terlihat. >>> hash.hexdigest() '781e****************************' # Hasil dari Base64-encoding hash MD5 yang salah. >>> base64.b64encode(hash.hexdigest()) 'Nzgx****************************************'