価格の確認の復号化

オークションで広告掲載を落札した場合、Google からその落札費用の情報をもらうことができます。それには、広告を定義する HTML スニペットに WINNING_PRICE マクロを含めると、落札費用が暗号化されて返されます。次のトピックでは、アプリケーションで落札費用情報を復号化する方法について説明します。

  1. シナリオ
  2. 必要なもの
  3. サンプル コード
  4. 暗号化スキーム
  5. 復号化スキーム
  6. 古いレスポンス攻撃の検出

シナリオ

  1. アプリケーションの HTML スニペットに WINNING_PRICE マクロを含めると、このマクロが Google に返されます。
  2. Google に返されたマクロは落札費用に置き換えられます(パディングされていないウェブセーフの Base64 エンコーディング(RFC 3548)が使用されます)。
  3. 置き換えられたスニペットから、事前に指定した形式で確認情報が渡されます。たとえば、広告の一部として表示される目に見えないピクセル リクエストの URL の中で確認情報が渡されます。
  4. サーバー上のアプリケーションで、落札費用情報を Base64 でデコードし、その結果を復号化します。

必要なもの

SHA-1 HMAC(Openssl など)をサポートする暗号化ライブラリが必要になります。

サンプル コード

サンプル コードは Java と C++ で提供され、http://code.google.com/p/privatedatacommunicationprotocol からダウンロードできます。

  • Java のサンプル コードでは、Apache Commons プロジェクトの Base64 デコーダが使用されていますが、必要な部分のコードは参照実装に含まれて自己完結しているため、Apache Commons コードをダウンロードする必要はありません。

  • C++ のサンプル コードでは、OpenSSL Base64 BIO メソッドが使用されています。このメソッドは、ウェブセーフの Base64 エンコーディング文字列(RFC 3548)を入力してデコードします。通常、ウェブセーフの Base64 文字列では「=」のパディングが「.」に置き換えられますが、マクロの置換では暗号化された費用はパディングされません。OpenSSL ではパディングされていない文字列に対して問題が発生するため、参照実装でパディングを追加します。

トップへ戻る

暗号化スキーム

費用は、十分なセキュリティに配慮しながらサイズのオーバーヘッドを最小限に抑えるよう設計されたカスタム暗号化スキームを使用して暗号化されます。この暗号化スキームでは、鍵付き HMAC アルゴリズムを使用して、固有のインプレッション イベント ID に基づいてシークレット パッドを生成します。

暗号化された費用は 28 バイトの固定長で、16 バイトの初期化ベクトル、8 バイトの暗号化テキスト、4 バイトの整合性シグニチャで構成されます。暗号化された費用は、RFC 3548 に基づいて、パディング文字が省略されたウェブセーフ Base64 でエンコードされています。したがって、28 バイトの暗号化された費用は、38 文字のウェブセーフ Base64 文字列としてエンコードされます。

暗号化されたフォーマットは次のようになります。

        {initialization_vector (16 bytes)}{encrypted_price (8 bytes)}
        {integrity (4 bytes)}

落札費用は、<price xor HMAC(encryption_key, initialization_vector)> として暗号化されるため、復号化では HMAC(encryption_key,initialization_vector) を計算し、暗号化された費用との排他的論理和をとって復号化します。整合性を検証する段階では、<HMAC(integrity_key, price||initialization_vector)> の 4 バイトを使用します(|| は連結を意味します)。

入力

iv 初期化ベクトル(16 バイト - インプレッションに固有)
e_key 暗号化キー(32 バイト - アカウント設定時に提供される)
i_key 整合性キー(32 バイト - アカウント設定時に提供される)
price (8 バイト - アカウントの通貨のマイクロ単位)

表記

hmac(k, d) データ d(キー k を使用)の SHA-1 HMAC
a || b 文字列 a と文字列 b の連結

擬似コード

pad = hmac(e_key, iv)  // 最初の 8 バイトenc_price = pad <xor> price
signature = hmac(i_key, price || iv)  // 最初の 4 バイト

final_message = WebSafeBase64Encode( iv || enc_price || signature )

トップへ戻る

復号化スキーム

復号化コードでは、暗号化キーを使用して費用を復号化し、整合性キーで整合性ビットを検証する必要があります。これらのキーはアカウントの設定時に提供されます。実装を構成する具体的な方法については何も制約がなく、ほとんどの部分をサンプル コードから抜粋して、必要に応じて変更できます。

入力

e_key 暗号化キー(32 バイト - アカウント設定時に提供される)
i_key 整合性キー(32 バイト - アカウント設定時に提供される)
final_message 38 文字(ウェブセーフの Base64 でエンコード)

擬似コード

enc_price = WebSafeBase64Decode(final_message)
(iv, p, sig) = dec_price -- split up according to fixed lengths
price_pad = hmac(e_key, iv)
price = p <xor> price_pad
conf_sig = hmac(i_key, price || iv)
success = (conf_sig == sig)

トップへ戻る

古いレスポンス攻撃の検出

古いレスポンスやリプレー、攻撃を検出するには、タイムゾーンの違いを考慮したうえで、タイムスタンプがシステム時刻と大幅に異なるレスポンスをフィルタすることをおすすめします。

初期化ベクトルの最初の 8 バイトにはタイムスタンプが含まれています。タイムスタンプは、次のような C++ 関数を使用して取得できます。

void GetTime(const char* iv, struct timeval* tv) {
    uint32 val;
    memcpy(&val, iv, sizeof(val));
    tv->tv_sec = htonl(val);
    memcpy(&val, iv+sizeof(val), sizeof(val));
    tv->tv_usec = htonl(val)
}

タイムスタンプは、次のような C++ コードを使用して人間が読み取れる形式に変換できます。

struct tm tm;
localtime_r(&tv->tv_sec, &tm);

printf("%04d-%02d-%02d|%02d:%02d:%02d.%06ld",

    tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
    tm.tm_hour, tm.tm_min, tm.tm_sec,
    tv_.tv_usec);

トップへ戻る

 

フィードバックを送信...

DoubleClick Ad Exchange Real-Time Bidding Protocol