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

ApsaraMQ for RocketMQ:リクエスト署名

最終更新日:Mar 12, 2026

ApsaraMQ for RocketMQ は、Authorization ヘッダー内の署名を検証することで、すべての HTTP API リクエストを認証します。以下のセクションでは、有効な署名を構築し、それをリクエストにアタッチする方法について説明します。

認証の仕組み

ApsaraMQ for RocketMQ は、対称暗号化を使用して各リクエスト送信者の ID を検証します。

  1. ご利用の AccessKey Secret を署名キーとして使用し、リクエストコンテンツから署名を構築します。

  2. 署名を HTTP リクエストの Authorization ヘッダーにアタッチします。

  3. サーバーは、同じアルゴリズムとご利用の AccessKey Secret を使用して、予期される署名を計算します。

  4. 2 つの署名が一致する場合、リクエストは認証されます。そうでない場合、サーバーは HTTP 403 でリクエストを拒否します。

前提条件

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

  • AccessKey ペア (AccessKey ID と AccessKey Secret) -- 詳細については、「AccessKey ペアの作成」をご参照ください。

Apsara Stack は、各ユーザーに AccessKey ペアを発行します。AccessKey ペアは Apsara Uni-manager 管理コンソールで申請および管理できます。AccessKey ペアは次の 2 つの部分で構成されます。

コンポーネント目的
AccessKey IDリクエストの送信者を識別します
AccessKey Secretリクエストに署名して、ご利用の ID を証明します。この値は厳重に機密保持してください

Authorization ヘッダーのフォーマット

Authorization ヘッダーを次のフォーマットで設定します。

MQ <AccessKey ID>:<Signature>

プレースホルダー値の例:

MQ LTAI5tExampleKey:dGhpcyBpcyBhbiBleGFtcGxlIHNpZw==

署名の構築

有効な署名を構築するには、署名対象文字列の組み立て、HMAC-SHA1 ハッシュの計算、および結果の Base64 エンコードの 3 つのステップが必要です。

Step 1: 署名対象文字列の組み立て

以下のフィールドを改行文字 (\n) で区切り、単一の UTF-8 文字列に連結します。

HTTP_METHOD + "\n"
+ "\n"
+ CONTENT-TYPE + "\n"
+ DATE + "\n"
+ "x-mq-version:" + MQVersion + "\n"
+ CanonicalizedResource

次の表は、各フィールドについて説明しています。

フィールド説明値またはフォーマット
HTTP_METHODHTTP メソッド (大文字)PUT, GET, POST, または DELETE
CONTENT-TYPEリクエストボディのメディアタイプtext/xml; charset=utf-8
DATERFC 2616 フォーマット (協定世界時 (UTC)) のリクエストタイムスタンプ例: Thu, 07 Mar 2012 18:49:58 GMT
MQVersionApsaraMQ for RocketMQ API バージョン2015-06-06
CanonicalizedResourceクエリパラメーターを含む、アクセスされるリソースの URI例: /topics/abc/messages?consumer=GID_abc
説明

署名対象文字列の 2 行目は意図的に空です。改行文字を含めますが、コンテンツは含めません。

コンシュームリクエストの署名対象文字列の例:

POST

text/xml; charset=utf-8
Thu, 07 Mar 2012 18:49:58 GMT
x-mq-version:2015-06-06
/topics/abc/messages?consumer=GID_abc

Step 2: HMAC-SHA1 ハッシュの計算

ご利用の AccessKey Secret を署名キーとして使用し、署名対象文字列に HMAC-SHA1 アルゴリズム (RFC 2104) を適用します。

Step 3: 結果の Base64 エンコード

バイナリ HMAC-SHA1 出力を Base64 エンコードして、最終署名文字列を生成します。

完全な数式:

Signature = base64(hmac-sha1(AccessKeySecret, StringToSign))

関数リファレンス

関数説明
hmac-sha1(key, message)SHA-1 ハッシュアルゴリズムを使用して HMAC ダイジェストを計算します。これは、RFC 2104 で定義されています。キー は、AccessKey Secret です。
base64(data)バイナリデータを Base64 文字列にエンコードします。

完全な例

この例では、次のパラメーターを持つメッセージ消費リクエストに署名します。

パラメーター
HTTP メソッドPOST
Content-Typetext/xml; charset=utf-8
DateThu, 07 Mar 2012 18:49:58 GMT
API バージョン2015-06-06
リソース URI/topics/abc/messages?consumer=GID_abc
AccessKey IDLTAI5tExampleKey
AccessKey SecretxXxExampleSecretxXx

Step 1 -- 署名対象文字列の組み立て:

POST

text/xml; charset=utf-8
Thu, 07 Mar 2012 18:49:58 GMT
x-mq-version:2015-06-06
/topics/abc/messages?consumer=GID_abc
説明

POST の後の空白行は、意図的に空にされた 2 行目です。

Step 2 および 3 -- HMAC-SHA1 の計算と Base64 エンコード:

Signature = base64(hmac-sha1("xXxExampleSecretxXx", StringToSign))

結果の Authorization ヘッダー:

Authorization: MQ LTAI5tExampleKey:<computed-signature>

<computed-signature> を Base64 エンコードされた HMAC-SHA1 出力に置き換えます。

コード例

次の例は、一般的なプログラミング言語で署名を生成する方法を示しています。各例は、署名対象文字列を構築し、HMAC-SHA1 ハッシュを計算し、結果を Base64 エンコードします。

Python

import hmac
import hashlib
import base64
import os
from email.utils import formatdate

# Obtain credentials from environment variables.
access_key_id = os.environ["MQ_ACCESS_KEY_ID"]
access_key_secret = os.environ["MQ_ACCESS_KEY_SECRET"]

# Request parameters
http_method = "POST"
content_type = "text/xml; charset=utf-8"
date = formatdate(usegmt=True)  # RFC 2616 format, e.g. "Thu, 07 Mar 2012 18:49:58 GMT"
mq_version = "2015-06-06"
canonicalized_resource = "/topics/abc/messages?consumer=GID_abc"

# Step 1: Assemble the string-to-sign.
string_to_sign = (
    http_method + "\n"
    + "\n"
    + content_type + "\n"
    + date + "\n"
    + "x-mq-version:" + mq_version + "\n"
    + canonicalized_resource
)

# Step 2-3: Compute HMAC-SHA1 and Base64-encode.
signature = base64.b64encode(
    hmac.new(
        access_key_secret.encode("utf-8"),
        string_to_sign.encode("utf-8"),
        hashlib.sha1,
    ).digest()
).decode("utf-8")

# Build the Authorization header.
authorization = f"MQ {access_key_id}:{signature}"
print(authorization)

Java

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.Locale;

public class MqSignature {
    public static void main(String[] args) throws Exception {
        // Obtain credentials from environment variables.
        String accessKeyId = System.getenv("MQ_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("MQ_ACCESS_KEY_SECRET");

        // Request parameters
        String httpMethod = "POST";
        String contentType = "text/xml; charset=utf-8";
        String date = DateTimeFormatter
                .ofPattern("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US)
                .format(ZonedDateTime.now(ZoneOffset.UTC));
        String mqVersion = "2015-06-06";
        String canonicalizedResource = "/topics/abc/messages?consumer=GID_abc";

        // Step 1: Assemble the string-to-sign.
        String stringToSign = httpMethod + "\n"
                + "\n"
                + contentType + "\n"
                + date + "\n"
                + "x-mq-version:" + mqVersion + "\n"
                + canonicalizedResource;

        // Step 2-3: Compute HMAC-SHA1 and Base64-encode.
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(new SecretKeySpec(
                accessKeySecret.getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
        byte[] rawSignature = mac.doFinal(
                stringToSign.getBytes(StandardCharsets.UTF_8));
        String signature = Base64.getEncoder().encodeToString(rawSignature);

        // Build the Authorization header.
        String authorization = "MQ " + accessKeyId + ":" + signature;
        System.out.println(authorization);
    }
}

Go

package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"os"
	"time"
)

func main() {
	// Obtain credentials from environment variables.
	accessKeyID := os.Getenv("MQ_ACCESS_KEY_ID")
	accessKeySecret := os.Getenv("MQ_ACCESS_KEY_SECRET")

	// Request parameters
	httpMethod := "POST"
	contentType := "text/xml; charset=utf-8"
	date := time.Now().UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT")
	mqVersion := "2015-06-06"
	canonicalizedResource := "/topics/abc/messages?consumer=GID_abc"

	// Step 1: Assemble the string-to-sign.
	stringToSign := httpMethod + "\n" +
		"\n" +
		contentType + "\n" +
		date + "\n" +
		"x-mq-version:" + mqVersion + "\n" +
		canonicalizedResource

	// Step 2-3: Compute HMAC-SHA1 and Base64-encode.
	mac := hmac.New(sha1.New, []byte(accessKeySecret))
	mac.Write([]byte(stringToSign))
	signature := base64.StdEncoding.EncodeToString(mac.Sum(nil))

	// Build the Authorization header.
	authorization := fmt.Sprintf("MQ %s:%s", accessKeyID, signature)
	fmt.Println(authorization)
}

Node.js

const crypto = require("crypto");

// Obtain credentials from environment variables.
const accessKeyId = process.env.MQ_ACCESS_KEY_ID;
const accessKeySecret = process.env.MQ_ACCESS_KEY_SECRET;

// Request parameters
const httpMethod = "POST";
const contentType = "text/xml; charset=utf-8";
const date = new Date().toUTCString(); // RFC 2616 format
const mqVersion = "2015-06-06";
const canonicalizedResource = "/topics/abc/messages?consumer=GID_abc";

// Step 1: Assemble the string-to-sign.
const stringToSign = [
  httpMethod,
  "",
  contentType,
  date,
  `x-mq-version:${mqVersion}`,
  canonicalizedResource,
].join("\n");

// Step 2-3: Compute HMAC-SHA1 and Base64-encode.
const signature = crypto
  .createHmac("sha1", accessKeySecret)
  .update(stringToSign, "utf-8")
  .digest("base64");

// Build the Authorization header.
const authorization = `MQ ${accessKeyId}:${signature}`;
console.log(authorization);

トラブルシューティング

次の表は、一般的な署名エラーとそのソリューションを示しています。

エラー原因ソリューション
HTTP 403: 署名の不一致署名対象文字列がサーバーの期待と一致しません署名対象文字列を出力し、各フィールドを確認します。2 行目の空白行が存在し、余分な空白が追加されていないことを確認してください。
HTTP 403: 日付のずれが大きすぎますDATE ヘッダーの値が、サーバーの時計と大きく異なっていますご利用のシステム時刻を NTP サーバーと同期し、協定世界時 (UTC) を使用してください。
HTTP 403: 無効な AccessKey IDAccessKey ID が存在しないか、無効になっていますコンソールで AccessKey ID が正しいか、アクティブな状態かを確認してください。
実行ごとに署名が異なりますDATEDATE ヘッダーはリクエストごとに変更されるため、毎回異なる署名が生成されますこれは予期される動作です。各リクエストに対して新しい署名を生成してください。
エンコーディングエラー署名対象文字列が UTF-8 でエンコードされていませんすべての文字列操作で UTF-8 エンコーディングを使用していることを確認してください。

制約事項

  • 署名対象文字列は UTF-8 エンコーディングを使用する必要があります。

  • DATE ヘッダーの値は協定世界時 (UTC) である必要があります。RFC 2616 日付フォーマット: Day, DD Mon YYYY HH:MM:SS GMT を使用してください。

  • Authorization ヘッダーはすべての HTTP リクエストに含める必要があります。