すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:Java を使用した OSS での署名ヘッダーのアップロード例

最終更新日:Mar 21, 2026

可能な限り OSS ソフトウェア開発キット (SDK) を使用してください — SDK では署名の計算が自動的に処理されます。SDK を使用できない場合、または HTTP 経由で PutObject API を直接呼び出す必要がある場合は、このトピックで、HMAC-SHA1 を使用して Java で Authorization リクエストヘッダーを手動で構築する方法について説明します。

前提条件

開始する前に、以下を確認してください。

  • JDK 1.8

  • Apache Commons Codec ライブラリがプロジェクトに追加されています(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'

仕組み

PutObject リクエストの署名には、次の 4 つのステップがあります。

  1. StringToSign を作成する — HTTP メソッド、空の Content-MD5 および Content-Type フィールド、GMT 形式の Date、および CanonicalizedResource を連結します。

  2. HMAC-SHA1 署名の計算 — AccessKey Secret を使用して StringToSign に署名します。

  3. 署名の Base64 エンコード — 生の HMAC バイトをエンコードして、印刷可能な署名文字列を生成します。

  4. 「Authorization」ヘッダーを設定する — AccessKey ID と署名を、OSS <AccessKeyID>:<Signature> の形式で組み合わせます。

StringToSign のフォーマット

PutObject リクエストの StringToSign は、次の構造に従います。

StringToSign =
  VERB + "\n"
  + Content-MD5 + "\n"       (empty in this example)
  + Content-Type + "\n"      (empty in this example)
  + Date + "\n"
  + CanonicalizedResource

このトピックの例では、StringToSign は次のようになります。

PUT\n
\n
\n
Thu, 22 May 2025 12:00:00 GMT\n
/xx/panda/102283/111.txt
注: 2 つの空白行は、空の Content-MD5 および Content-Type フィールドに対応しています。両方とも、空の場合でも存在する必要があります。

サンプルコード

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 {
// Add request content
connection= (HttpURLConnection) url1.openConnection();
// Set HTTP connection properties
connection.setDoOutput(true);// within the HTTP body, it needs to be set to true, which is false by default.
connection.setRequestMethod("PUT"); // submit HTTP-provided functions such as GET, POST, DELETE, and PUT as needed.
// connection. Setusecvisits (false);// specify the cache. Note: The request method must be set to post.
// connection.setInstanceFollowRedirects(true);
connection.setRequestProperty("Date", date); // Set the URL and domain of the requested server, for example, bucket*. **. ***. ***.
connection.setRequestProperty("Authorization", Authorization);// Set the request format in Json. You can also set the format in XML.
// connection.setRequestProperty("Content-Length", obj.toString().getBytes().length + ""); // set the Length of the requested object.



connection.setReadTimeout(10000);// Set the read timeout.
connection.setConnectTimeout(10000);// Set the connection timeout.
connection.connect();
 OutputStream out = connection.getOutputStream();// write data to the object output stream, which will be stored in the memory buffer.
out.write(new String("test data").getBytes()); // out.write(new String("test data").getBytes()); // refresh the output stream of the object to write any bytes to the potential stream.
out.flush();
// Close the flow object. At this time, no more data can be written to the object output stream, and previously written data exists in the memory buffer.
out.close();
// Read the response.
if (connection.getResponseCode()==200)      {
// Get an input stream from the server.
InputStreamReader inputStream =new InputStreamReader(connection.getInputStream());// call the getInputStream() function of the HttpURLConnection object to send the complete HTTP request message encapsulated in the memory buffer to the 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());
}
// Disconnect.
connection.disconnect();
System.out.println("OK  "+url1);
} catch (IOException e) {
e.printStackTrace();
}
}
}

コードを実行する前に、プレースホルダーの値を置き換えてください。

プレースホルダー説明例
"your bucket name"ご利用の OSS バケット名my-bucket
"your AccessKey"ご利用の AccessKey IDLTAI5tXxx
"your AccessSecret"ご利用の AccessKey SecretxXxXxXx
注: buildSignData() メソッドは StringToSign の HTTP メソッドとして "PUT" をハードコーディングしますが、main() では VERB = "GET" が設定され、connection.setRequestMethod("PUT") が呼び出されます。この不一致はソースコードに存在します。実際の実装で使用する HTTP メソッドに合わせて、StringToSign の構築と接続メソッドの両方を調整してください。

次のステップ