URL署名link

URL署名機能は変換パラメータに署名パラメータを含めることで、外部のユーザーによるURLの書き換えを防止する機能です。 署名パラメータはリクエストURLから特定の方法で計算する必要があります。 この機能を利用することで、たとえばオーバーレイー合成のパラメータを除去してオリジナル画像を取り出すといったことを防ぐことができます。

URL署名の有効化link

URL署名機能はオリジンごとに設定します。 URL署名機能を有効にするには、オリジン設定画面でにチェックを入れます。 URL署名機能が有効になっているオリジンのホスト名に対して、署名パラメータを含まないURLでリクエストするとエラー(403 Forbidden)が応答されます。

署名パラメータlink

Key Value Type Default Description
sig string (なし) シグネチャ

URL署名機能では、sigパラメータにシグネチャを指定してリクエストします。 sigパラメータを指定する代わりに、HTTPリクエストヘッダのX-ImageFlux-Signatureフィールドにシグネチャを指定することもできます。 シグネチャ(signature)の計算方法を以下の擬似コードに示します。

version := "1"
value := BASE64URL(HMAC-SHA-256(signing-secret, path))
signature := version + "." + value
  • ここでBASE64URL関数はURLセーフな文字列を用いたBase64エンコードを行う関数です (詳細はRFC4648 Section 5を参照してください)。
  • HMAC-SHA-256関数はSHA-256ハッシュ関数を用いたHMACを計算する関数です。
  • path変数はURLのパス(スキーム名とホスト名を除いたもの)を指します。
  • 正規化されていないパスが指定された場合は端末やブラウザによって正常に動作しない場合があります。ImageFluxではRFC-3986 Section 6.2.2による正規化を想定していますが、正規化されていないパスに対する動作は保証されていません。

URL署名の例link

画像変換パラメータと sigパラメータは任意の順で指定できますが、sigパラメータ以外のパラメータは署名計算時と同じ順序で指定する必要があります。

元のURL https://p1-47e91401.imageflux.jp/c/w=200/images/1.jpg
Signing Secret testsigningsecret
シグネチャ 1.tiKX5u2kw6wp9zDgl1tLiOIi8IsoRIBw8fVgVc0yrNg=
URL https://p1-47e91401.imageflux.jp/c/sig=1.tiKX5u2kw6wp9zDgl1tLiOIi8IsoRIBw8fVgVc0yrNg=,w=200/images/1.jpg
元のURL https://p1-47e91401.imageflux.jp/images/1.jpg
Signing Secret testsigningsecret
シグネチャ 1.-Yd8m-5pXPihiZdlDATcwkkgjzPIC9gFHmmZ3JMxwS0=
URL https://p1-47e91401.imageflux.jp/c/sig=1.-Yd8m-5pXPihiZdlDATcwkkgjzPIC9gFHmmZ3JMxwS0=/images/1.jpg

サンプルコードlink

PHPlink

<?php

$signing_secret = "testsigningsecret";
$path = "/images/1.jpg";

$hash = hash_hmac("sha256", $path, $signing_secret, true);
$signature = "1." . rtrim(strtr(base64_encode($hash), "+/", "-_"), "=");

echo $signature;

Rubylink

require "openssl"
require "base64"

signing_secret = "testsigningsecret"
path = "/images/1.jpg"

hash = OpenSSL::HMAC.digest("sha256", signing_secret, path)
signature = "1." + Base64.urlsafe_encode64(hash)

puts signature

Golink

package main

import (
  "crypto/hmac"
  "crypto/sha256"
  "encoding/base64"
  "fmt"
)

func main() {
  signingSecret := "testsigningsecret"
  path := "/images/1.jpg"

  fmt.Printf("Signing Secret: %s\n", signature(signingSecret, path))
}

func signature(secret, path string) string {
  mac := hmac.New(sha256.New, []byte(secret))
  mac.Write([]byte(path))

  return "1." + base64.RawURLEncoding.EncodeToString(mac.Sum(nil))
}