Untuk memastikan validitas dan keamanan permintaan PostObject, Anda harus menyertakan tanda tangan dalam permintaan tersebut. Tanda tangan V4 dihitung dengan mengenkripsi serangkaian parameter permintaan, termasuk kebijakan dan masa berlaku, menggunakan rahasia AccessKey, waktu saat ini, dan wilayah. Setelah server aplikasi menghasilkan tanda tangan, informasi seperti tanda tangan dan kebijakan unggah dikembalikan ke klien. Klien kemudian menggunakan informasi ini untuk membuat permintaan unggah. OSS akan memverifikasi validitas tanda tangan setelah menerima permintaan unggah. Hanya permintaan dengan tanda tangan yang valid yang diizinkan, sementara permintaan yang gagal verifikasi akan ditolak.
Tanda tangan dalam permintaan PostObject
Untuk meningkatkan keamanan data, permintaan PostObject mengintegrasikan algoritma tanda tangan V4. Elemen formulir dan bidang formulir kebijakan memainkan peran penting dalam memastikan validitas dan keamanan permintaan PostObject.
Elemen formulir
Formulir adalah kumpulan bidang yang terdapat dalam permintaan PostObject untuk mengirimkan informasi tentang objek yang ingin diunggah beserta metadata-nya. Tabel berikut menjelaskan elemen formulir unik dari tanda tangan V4 dalam permintaan PostObject. Untuk informasi lebih lanjut tentang elemen formulir umum, lihat Elemen formulir.
Elemen | Tipe | Diperlukan | Deskripsi |
x-oss-signature-version | String | Ya | Versi tanda tangan dan algoritma yang digunakan untuk menghitung tanda tangan. Atur nilainya menjadi OSS4-HMAC-SHA256. |
x-oss-credential | String | Ya | Kredensial yang dapat Anda gunakan untuk menghitung tanda tangan. Format:
|
x-oss-date | String | Ya | Waktu ketika permintaan dilakukan. Waktu harus mengikuti standar ISO 8601. Contoh:
|
x-oss-signature | String | Ya | Deskripsi yang digunakan untuk verifikasi tanda tangan. Nilainya dihitung dengan mengenkripsi string kebijakan yang dikodekan Base64 menggunakan HMAC-SHA256, lalu mengonversi hash biner yang diperoleh menggunakan HMAC-SHA256 ke format heksadesimal. |
policy
Bidang formulir policy dalam permintaan PostObject digunakan untuk menentukan waktu kedaluwarsa dan kondisi permintaan PostObject yang diinisiasi untuk mengunggah objek menggunakan formulir HTML. Nilai dari bidang formulir policy adalah string JSON yang membatasi permintaan PostObject dengan menentukan beberapa parameter, seperti nama bucket tempat objek akan diunggah, awalan dalam nama objek, periode validitas permintaan, metode HTTP yang diizinkan, serta ukuran dan konten objek.
Bidang formulir policy harus mencakup parameter expiration dan conditions. Parameter x-oss-security-token hanya diperlukan jika Anda menggunakan token keamanan untuk membangun tanda tangan dalam permintaan PostObject. Parameter ini tidak diperlukan jika Anda menggunakan pasangan AccessKey untuk membangun tanda tangan.
{
"expiration": "2023-12-03T13:00:00.000Z",
"conditions": [
{"bucket": "examplebucket"},
{"x-oss-signature-version": "OSS4-HMAC-SHA256"},
{"x-oss-credential": "AKIDEXAMPLE/20231203/cn-hangzhou/oss/aliyun_v4_request"},
{"x-oss-security-token": "CAIS******"},
{"x-oss-date": "20231203T121212Z"},
["content-length-range", 1, 10],
["eq", "$success_action_status", "201"],
["starts-with", "$key", "user/eric/"],
["in", "$content-type", ["image/jpg", "image/png"]],
["not-in", "$cache-control", ["no-cache"]]
]
}Parameter yang diperlukan dalam bidang formulir policy:
expiration
Parameter expiration menentukan waktu kedaluwarsa permintaan. Waktu harus mengikuti standar ISO 8601 dan dalam GMT. Contohnya,
2023-12-03T13:00:00.000Zmenunjukkan bahwa permintaan PostObject harus dikirim sebelum pukul 13:00 pada 3 Desember 2023.conditions
Parameter conditions adalah daftar yang menentukan nilai valid dari bidang formulir dalam permintaan PostObject.
Parameter
Tipe
Diperlukan
Deskripsi
Mode pencocokan
bucket
String
Tidak
Nama bucket.
bucket
x-oss-signature-version
String
Ya
Versi tanda tangan dan algoritma yang digunakan untuk menghitung tanda tangan. Atur nilainya menjadi OSS4-HMAC-SHA256.
x-oss-signature-version
x-oss-credential
String
Ya
Kredensial yang dapat Anda gunakan untuk menghitung tanda tangan. Format:
<AccessKeyId>/<date>/<region>/oss/aliyun_v4_requestAccessKeyId: ID AccessKey dari pasangan AccessKey.
date: tanggal ketika permintaan dilakukan.
region: ID wilayah Alibaba Cloud tempat bucket yang ingin Anda akses berada. Contoh: cn-hangzhou.
oss: nama layanan yang diminta. Atur nilainya menjadi oss.
aliyun_v4_request: deskripsi versi tanda tangan dalam permintaan. Atur nilainya menjadi aliyun_v4_request.
x-oss-credential
x-oss-security-token
String
Tidak
Parameter ini hanya diperlukan ketika Anda menggunakan token keamanan untuk membangun tanda tangan dalam permintaan PostObject. Anda dapat memanggil operasi AssumeRole STS untuk mendapatkan token keamanan.
x-oss-security-token
x-oss-date
String
Ya
Waktu ketika permintaan dilakukan. Waktu harus mengikuti standar ISO 8601. Contoh:
20231203T121212Z.Offset hingga 15 menit setelah permintaan dilakukan diperbolehkan. Oleh karena itu, waktu ketika server menerima permintaan bisa hingga 15 menit lebih lambat daripada waktu yang ditentukan oleh
x-oss-date. Ini memastikan bahwa permintaan dapat diproses sesuai harapan meskipun ada latensi transmisi jaringan atau perbedaan waktu antara klien dan server.Permintaan memiliki periode validitas hingga tujuh hari. Tujuh hari setelah waktu yang ditentukan oleh
x-oss-date, OSS akan menolak permintaan dan melaporkan kesalahan. Ini memastikan ketepatan waktu dan keamanan permintaan serta mencegah pengiriman jahat permintaan yang kedaluwarsa atau ditandatangani.Waktu yang ditentukan oleh
x-oss-datedigunakan sebagai cap waktu untuk string yang ditandatangani. Nilai tersebut harus sama dengan nilai bidang date dalam kunci turunan dan nilai bidang x-oss-date dalam bidang formulir kebijakan.
x-oss-date
content-length-range
String
Tidak
Ukuran minimum dan maksimum objek yang ingin Anda unggah. Unit: byte.
content-length-range
success_action_status
String
Tidak
Kode status HTTP yang dikembalikan setelah objek diunggah.
eq, starts-with, in, dan not-in
key
String
Tidak
Nama objek yang ingin Anda unggah.
eq, starts-with, in, dan not-in
content-type
String
Tidak
Jenis objek yang ingin Anda unggah.
eq, starts-with, in, dan not-in
cache-control
String
Tidak
Perilaku caching objek.
eq, starts-with, in, dan not-in
Proses perhitungan tanda tangan
Buat kebijakan yang dikodekan UTF-8.
Buat string untuk ditandatangani.
Kodekan Base64 kebijakan tersebut untuk menghasilkan string yang dapat ditransmisikan secara aman sebagai string yang akan ditandatangani.
Hitung kunci penandatanganan.
Enkripsi string yang akan ditandatangani menggunakan HMAC-SHA256. Gunakan kunci turunan dari akun sebagai kunci untuk menggunakan HMAC-SHA256.
Hitung tanda tangan.
Konversi hash biner yang dihitung menggunakan HMAC-SHA256 menjadi string heksadesimal. String heksadesimal yang diperoleh adalah tanda tangan yang digunakan untuk memverifikasi integritas dan validitas permintaan.
Contoh
Kode sampel berikut memberikan contoh cara menggunakan kebijakan sebelumnya untuk menghitung tanda tangan V4 untuk permintaan PostObject menggunakan OSS SDK for Java:
Gunakan Access Key (AK) atau Secret Key (SK)
import com.aliyun.oss.common.utils.BinaryUtil; import org.apache.commons.codec.binary.Base64; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; public class Demo { public static void main(String[] args) throws Exception { // Sebelum menjalankan kode sampel, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi. String accesskeyid = System.getenv().get("OSS_ACCESS_KEY_ID"); String accesskeysecret = System.getenv().get("OSS_ACCESS_KEY_SECRET"); // Langkah 1: Buat kebijakan. ObjectMapper mapper = new ObjectMapper(); Map<String, Object> policy = new HashMap<>(); policy.put("expiration", "2024-12-03T13:00:00.000Z"); List<Object> conditions = new ArrayList<>(); Map<String, String> bucketCondition = new HashMap<>(); bucketCondition.put("bucket", "examplebucket"); conditions.add(bucketCondition); Map<String, String> signatureVersionCondition = new HashMap<>(); signatureVersionCondition.put("x-oss-signature-version", "OSS4-HMAC-SHA256"); conditions.add(signatureVersionCondition); Map<String, String> credentialCondition = new HashMap<>(); credentialCondition.put("x-oss-credential", "accesskeyid/20241203/cn-hangzhou/oss/aliyun_v4_request"); // Ganti variabel ini dengan ID AccessKey Anda. conditions.add(credentialCondition); Map<String, String> dateCondition = new HashMap<>(); dateCondition.put("x-oss-date", "20241203T121212Z"); conditions.add(dateCondition); conditions.add(Arrays.asList("content-length-range", 1, 10)); conditions.add(Arrays.asList("eq", "$success_action_status", "201")); conditions.add(Arrays.asList("starts-with", "$key", "user/eric/")); conditions.add(Arrays.asList("in", "$content-type", Arrays.asList("image/jpg", "image/png"))); conditions.add(Arrays.asList("not-in", "$cache-control", Arrays.asList("no-cache"))); policy.put("conditions", conditions); String jsonPolicy = mapper.writeValueAsString(policy); // Langkah 2: Buat string untuk ditandatangani. String stringToSign = new String(Base64.encodeBase64(jsonPolicy.getBytes())); System.out.println(stringToSign) // Langkah 3: Hitung kunci penandatanganan. byte[] dateKey = hmacsha256(("aliyun_v4" + accesskeysecret).getBytes(), "20231203"); byte[] dateRegionKey = hmacsha256(dateKey, "cn-hangzhou"); byte[] dateRegionServiceKey = hmacsha256(dateRegionKey, "oss"); byte[] signingKey = hmacsha256(dateRegionServiceKey, "aliyun_v4_request"); // Langkah 4: Hitung tanda tangan. byte[] result = hmacsha256(signingKey, stringToSign); String signature = BinaryUtil.toHex(result); System.out.println("signature:" + signature); } public static byte[] hmacsha256(byte[] key, String data) { try { // Inisialisasi SecretKeySpec, atur algoritma ke HMAC-SHA256, dan gunakan kunci yang disediakan. SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacSHA256"); // Dapatkan instance Mac dan gunakan metode getInstance untuk mengatur algoritma ke HMAC-SHA256. Mac mac = Mac.getInstance("HmacSHA256"); // Gunakan kunci untuk menginisialisasi instance Mac. mac.init(secretKeySpec); // Hitung nilai HMAC. Gunakan metode doFinal untuk menerima data yang akan dihitung dan mengembalikan hasil perhitungan sebagai array. byte[] hmacBytes = mac.doFinal(data.getBytes()); return hmacBytes; } catch (Exception e) { throw new RuntimeException("Gagal menghitung HMAC-SHA256", e); } } }Respon sampel:
signature:3908473f7dbfb79a102eaaa44ca1edec8d7058ce3bd1c624d59eb437463bd5d6Gunakan kredensial akses sementara
Saat menghitung tanda tangan untuk permintaan PostObject menggunakan kredensial akses sementara, Anda juga perlu mendapatkan token keamanan dengan memanggil operasi AssumeRole STS.
import com.aliyun.oss.common.utils.BinaryUtil; import org.apache.commons.codec.binary.Base64; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import com.aliyun.sts20150401.models.AssumeRoleResponse; import com.aliyun.sts20150401.models.AssumeRoleResponseBody; import com.aliyun.tea.TeaException; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.*; public class Demo { // Inisialisasi instance STSClient. public static com.aliyun.sts20150401.Client createStsClient() throws Exception { com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config() // Pastikan bahwa variabel lingkungan OSS_ACCESS_KEY_ID telah dikonfigurasi. .setAccessKeyId(System.getenv("OSS_ACCESS_KEY_ID")) // Pastikan bahwa variabel lingkungan OSS_ACCESS_KEY_SECRET telah dikonfigurasi. .setAccessKeySecret(System.getenv("OSS_ACCESS_KEY_SECRET")); // Endpoint config.endpoint = "sts.cn-hangzhou.aliyuncs.com"; return new com.aliyun.sts20150401.Client(config); } // Dapatkan token STS. public static AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials getCredential() throws Exception { com.aliyun.sts20150401.Client client = Demo.createStsClient(); com.aliyun.sts20150401.models.AssumeRoleRequest assumeRoleRequest = new com.aliyun.sts20150401.models.AssumeRoleRequest() // Pastikan bahwa variabel lingkungan OSS_STS_ROLE_ARN telah dikonfigurasi. .setRoleArn(System.getenv("OSS_STS_ROLE_ARN")) .setRoleSessionName("role_session_name");// Tentukan nama sesi. com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions(); try { // Tulis kode Anda sendiri untuk menampilkan respons operasi API jika diperlukan. AssumeRoleResponse response = client.assumeRoleWithOptions(assumeRoleRequest, runtime); // AccessKey ID, AccessKey secret, dan token STS yang diperlukan untuk operasi selanjutnya termasuk dalam credentials. return response.body.credentials; } catch (TeaException error) { // Tangani pengecualian dengan hati-hati dalam skenario bisnis aktual Anda dan jangan pernah abaikan pengecualian dalam proyek Anda. Pesan kesalahan yang ditampilkan dalam contoh ini hanya untuk referensi. // Pesan kesalahan. System.out.println(error.getMessage()); // URL untuk pemecahan masalah. System.out.println(error.getData().get("Recommend")); com.aliyun.teautil.Common.assertAsString(error.message); } catch (Exception _error) { TeaException error = new TeaException(_error.getMessage(), _error); // Tangani pengecualian dengan hati-hati dalam skenario bisnis aktual Anda dan jangan pernah abaikan pengecualian dalam proyek Anda. Pesan kesalahan yang ditampilkan dalam contoh ini hanya untuk referensi. // Pesan kesalahan. System.out.println(error.getMessage()); // URL untuk pemecahan masalah. System.out.println(error.getData().get("Recommend")); com.aliyun.teautil.Common.assertAsString(error.message); } return null; } public static void main(String[] args) throws Exception { AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials sts_data = getCredential(); String accesskeyid = sts_data.accessKeyId; String accesskeysecret = sts_data.accessKeySecret; String securitytoken = sts_data.securityToken; // Langkah 1: Buat kebijakan. ObjectMapper mapper = new ObjectMapper(); Map<String, Object> policy = new HashMap<>(); policy.put("expiration", "2024-12-03T13:00:00.000Z"); List<Object> conditions = new ArrayList<>(); Map<String, String> bucketCondition = new HashMap<>(); bucketCondition.put("bucket", "examplebucket"); conditions.add(bucketCondition); Map<String, String> signatureVersionCondition = new HashMap<>(); signatureVersionCondition.put("x-oss-signature-version", "OSS4-HMAC-SHA256"); conditions.add(signatureVersionCondition); Map<String, String> securityTokenCondition = new HashMap<>(); securityTokenCondition.put("x-oss-security-token", securitytoken); conditions.add(securityTokenCondition); Map<String, String> credentialCondition = new HashMap<>(); credentialCondition.put("x-oss-credential", "accesskeyid/20241203/cn-hangzhou/oss/aliyun_v4_request"); conditions.add(credentialCondition); Map<String, String> dateCondition = new HashMap<>(); dateCondition.put("x-oss-date", "20241203T121212Z"); conditions.add(dateCondition); conditions.add(Arrays.asList("content-length-range", 1, 10)); conditions.add(Arrays.asList("eq", "$success_action_status", "201")); conditions.add(Arrays.asList("starts-with", "$key", "user/eric/")); conditions.add(Arrays.asList("in", "$content-type", Arrays.asList("image/jpg", "image/png"))); conditions.add(Arrays.asList("not-in", "$cache-control", Arrays.asList("no-cache"))); policy.put("conditions", conditions); String jsonPolicy = mapper.writeValueAsString(policy); // Langkah 2: Buat string untuk ditandatangani. String stringToSign = new String(Base64.encodeBase64(jsonPolicy.getBytes())); // Langkah 3: Hitung kunci penandatanganan. byte[] dateKey = hmacsha256(("aliyun_v4" + accesskeysecret).getBytes(), "20231203"); byte[] dateRegionKey = hmacsha256(dateKey, "cn-hangzhou"); byte[] dateRegionServiceKey = hmacsha256(dateRegionKey, "oss"); byte[] signingKey = hmacsha256(dateRegionServiceKey, "aliyun_v4_request"); // Langkah 4: Hitung tanda tangan. byte[] result = hmacsha256(signingKey, stringToSign); String signature = BinaryUtil.toHex(result); System.out.println("signature:" + signature); } public static byte[] hmacsha256(byte[] key, String data) { try { // Inisialisasi SecretKeySpec, atur algoritma ke HMAC-SHA256, dan gunakan kunci yang disediakan. SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacSHA256"); // Dapatkan instance Mac dan gunakan metode getInstance untuk mengatur algoritma ke HMAC-SHA256. Mac mac = Mac.getInstance("HmacSHA256"); // Gunakan kunci untuk menginisialisasi instance Mac. mac.init(secretKeySpec); // Hitung nilai HMAC. Gunakan metode doFinal untuk menerima data yang akan dihitung dan mengembalikan hasil perhitungan sebagai array. byte[] hmacBytes = mac.doFinal(data.getBytes()); return hmacBytes; } catch (Exception e) { throw new RuntimeException("Gagal menghitung HMAC-SHA256", e); } } }Respon sampel:
signature:1e09438f7ad01af6b3e144b42c98929c68f8d090ce07f4c277b18d8b62d0aa02Kode sampel berikut memberikan contoh cara menghitung tanda tangan V4 untuk permintaan PostObject menggunakan OSS SDK for Python:
import base64 import hmac import hashlib import os def hmac_sha256(key, data): return hmac.new(key, data.encode('utf-8'), hashlib.sha256).digest() # Ambil ID AccessKey dan rahasia AccessKey dari variabel lingkungan. accesskeyid = os.getenv('OSS_ACCESS_KEY_ID') accesskeysecret = os.getenv('OSS_ACCESS_KEY_SECRET') # Tampilkan ID AccessKey. print(accesskeyid) # Periksa apakah variabel lingkungan telah diambil. if not accesskeyid or not accesskeysecret: raise ValueError("Variabel lingkungan yang diperlukan tidak ditemukan: OSS_ACCESS_KEY_ID atau OSS_ACCESS_KEY_SECRET") # Buat kebijakan. policy = '''{ "expiration": "2025-01-01T00:00:00.000Z", "conditions": [ {"x-oss-signature-version": "OSS4-HMAC-SHA256"}, {"x-oss-credential": "accesskeyid/20241105/cn-hangzhou/oss/aliyun_v4_request"}, // Ganti accesskeyid dengan ID access key Anda yang sebenarnya. {"x-oss-date": "20241105T065000Z"} ] }''' # Keluarkan kebijakan. print(policy) # Hitung string untuk ditandatangani. string_to_sign = base64.b64encode(policy.encode('utf-8')).decode('utf-8') print(string_to_sign) # Hitung kunci penandatanganan. date_key = hmac_sha256(f"aliyun_v4{accesskeysecret}".encode('utf-8'), "20241105") date_region_key = hmac_sha256(date_key, "cn-beijing") date_region_service_key = hmac_sha256(date_region_key, "oss") signing_key = hmac_sha256(date_region_service_key, "aliyun_v4_request") # Hitung tanda tangan. result = hmac_sha256(signing_key, string_to_sign) signature = result.hex() print("signature:", signature)Respon sampel:
signature:9e85d56429245283b1aca5bc2dc31e0020b95ac2de9e9b81b496994db602ba1e