All Products
Search
Document Center

Object Storage Service:Contoh mengunggah header signature di OSS menggunakan Java

Last Updated:Mar 21, 2026

Gunakan SDK OSS bila memungkinkan—SDK tersebut secara otomatis menangani perhitungan signature. Jika Anda tidak dapat menggunakan SDK dan perlu memanggil API PutObject langsung melalui HTTP, topik ini menjelaskan cara membuat header permintaan Authorization secara manual dalam Java menggunakan HMAC-SHA1.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

  • JDK 1.8

  • Pustaka Apache Commons Codec yang ditambahkan ke proyek Anda (menyediakan org.apache.commons.codec.binary.Base64)

Maven:

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>

Gradle:

implementation 'commons-codec:commons-codec:1.15'

Cara kerja

Menandatangani permintaan PutObject mencakup empat langkah berikut:

  1. Buat StringToSign — Gabungkan metode HTTP, bidang Content-MD5 dan Content-Type yang kosong, Date dalam format GMT, serta CanonicalizedResource.

  2. Hitung signature HMAC-SHA1 — Tandatangani StringToSign menggunakan rahasia AccessKey Anda.

  3. Encode signature dalam Base64 — Encode byte HMAC mentah untuk menghasilkan string signature yang dapat dicetak.

  4. Atur header Authorization — Gabungkan ID AccessKey Anda dan signature dalam format OSS <AccessKeyID>:<Signature>.

Format StringToSign

StringToSign untuk permintaan PutObject mengikuti struktur berikut:

StringToSign =
  VERB + "\n"
  + Content-MD5 + "\n"       (kosong dalam contoh ini)
  + Content-Type + "\n"      (kosong dalam contoh ini)
  + Date + "\n"
  + CanonicalizedResource

Untuk contoh dalam topik ini, StringToSign terlihat seperti:

PUT\n
\n
\n
Thu, 22 May 2025 12:00:00 GMT\n
/xx/panda/102283/111.txt
Catatan: Dua baris kosong tersebut merepresentasikan bidang Content-MD5 dan Content-Type yang kosong. Keduanya harus tetap disertakan meskipun nilainya kosong.

Kode contoh

import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
public class OssSignHeader {
private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
private final static String CHARSET_UTF8 = "utf8";
private final static String ALGORITHM = "HmacSHA1";
public static String hmacSha1(String data, String key) {
try {
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
mac.init(keySpec);
byte[] rawHmac;
rawHmac = mac.doFinal(data.getBytes(CHARSET_UTF8));
return new String(Base64.encodeBase64(rawHmac));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String buildSignData(String Date,String VERB,String CanonicalizedResource){
String signData = "PUT" + "\n"+ "\n"+ "\n"
+ Date + "\n"
 + CanonicalizedResource;
return signData;
}
public static String getGMTDate(){
Calendar cd = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String str = sdf.format(cd.getTime());
return str;
}
public static void main(String[] args) throws Exception{
String date = getGMTDate();
String ossBucket= "your bucket name";
 String accessKeyId= "your AccessKey";
 String secretAccessKey= "your AccessSecret";
 String resourcePath = "/xx/panda/102283/111.txt";
 String resourcePath1 = "panda/102283/111.txt";
String VERB = "GET";
 String url = "http://"+ossBucket+".oss-cn-hangzhou.aliyuncs.com/";
 String Signature = (hmacSha1(buildSignData(date,VERB,resourcePath),secretAccessKey));
 String Authorization = "OSS " + accessKeyId + ":" + Signature;
System.out.println(Authorization);
Map<String,String> head = new HashMap<String,String>();
head.put("Date",date);
head.put("Authorization",Authorization);
 URL url1 = new URL(url + resourcePath1);
HttpURLConnection connection ;
StringBuffer sbuffer=null;
try {
// Tambahkan konten permintaan
connection= (HttpURLConnection) url1.openConnection();
// Atur properti koneksi HTTP
connection.setDoOutput(true);// dalam body HTTP, harus diatur ke true, default-nya false.
connection.setRequestMethod("PUT"); // kirim fungsi yang disediakan HTTP seperti GET, POST, DELETE, dan PUT sesuai kebutuhan.
// connection. Setusecvisits (false);// tentukan cache. Catatan: Metode permintaan harus diatur ke post.
// connection.setInstanceFollowRedirects(true);
connection.setRequestProperty("Date", date); // Atur URL dan domain server yang diminta, misalnya bucket*. **. ***. ***.
connection.setRequestProperty("Authorization", Authorization);// Atur format permintaan dalam Json. Anda juga dapat mengatur format dalam XML.
// connection.setRequestProperty("Content-Length", obj.toString().getBytes().length + ""); // atur panjang objek yang diminta.



connection.setReadTimeout(10000);// Atur timeout baca.
connection.setConnectTimeout(10000);// Atur timeout koneksi.
connection.connect();
 OutputStream out = connection.getOutputStream();// tulis data ke aliran output objek, yang akan disimpan dalam buffer memori.
out.write(new String("test data").getBytes()); // out.write(new String("test data").getBytes()); // refresh aliran output objek untuk menulis semua byte ke aliran potensial.
out.flush();
// Tutup objek aliran. Pada titik ini, tidak ada lagi data yang dapat ditulis ke aliran output objek, dan data yang sebelumnya ditulis tersimpan dalam buffer memori.
out.close();
// Baca respons.
if (connection.getResponseCode()==200)      {
// Dapatkan aliran input dari server.
InputStreamReader inputStream =new InputStreamReader(connection.getInputStream());// panggil fungsi getInputStream() dari objek HttpURLConnection untuk mengirim pesan permintaan HTTP lengkap yang dikemas dalam buffer memori ke server.
BufferedReader reader = new BufferedReader(inputStream);



String lines;
sbuffer= new StringBuffer("");



while ((lines = reader.readLine()) != null) {
lines = new String(lines.getBytes(), "utf-8");
sbuffer.append(lines);                }
reader.close();
}else{
System.out.println(connection.getResponseCode());
}
// Putuskan koneksi.
connection.disconnect();
System.out.println("OK  "+url1);
} catch (IOException e) {
e.printStackTrace();
}
}
}

Ganti nilai placeholder berikut sebelum menjalankan kode:

PlaceholderDeskripsiContoh
"your bucket name"Nama Bucket OSS Andamy-bucket
"your AccessKey"ID AccessKey AndaLTAI5tXxx
"your AccessSecret"Rahasia AccessKey AndaxXxXxXx
Catatan: Metode buildSignData() secara hardcoded menggunakan "PUT" sebagai metode HTTP dalam StringToSign, sedangkan main() mengatur VERB = "GET" dan connection.setRequestMethod("PUT"). Ketidakkonsistenan ini terdapat pada kode sumber. Pastikan pembuatan StringToSign dan metode koneksi sesuai dengan metode HTTP yang benar-benar digunakan dalam implementasi Anda.

Langkah selanjutnya