料金の確認の復号

クリエイティブがオークションで勝った場合は 関連するマクロがクリエイティブに含まれている場合は

OpenRTB プロトコルを使用するようにビッダーが設定されている場合、 含まれている場合は、IAB の${AUCTION_PRICE}を使用してください マクロを使用します。

サポートが終了した Google RTB プロトコルをビッダーで使用している場合、クリエイティブは Google の %%WINNING_PRICE%% を使用する マクロを使用します。

これらのマクロが展開されると、落札価格が 暗号化されます。カスタム ディメンションは、たとえば 広告の一部としてレンダリングされた不可視ピクセル リクエスト:

<div>
  <script language='JavaScript1.1' src='https://example.com?creativeID=5837243'/>
  <img src='https://example.com/t.gif?price=${AUCTION_PRICE}' width='1' height='1'/>
</div>

${AUCTION_PRICE} マクロは、 動画クリエイティブをリクエストし、VAST のインプレッション URL にはない場合:

https://example.com/vast/v?price=${AUCTION_PRICE}

シナリオ

  1. OpenRTB 入札アプリケーションに ${AUCTION_PRICE} が含まれている マクロを Google に返すことができます。
  2. Google が、パディングなしのウェブセーフのマクロを落札価格に置き換えます base64 エンコード(RFC 3548)。
  3. スニペットは、選択した形式で確認を渡します。対象 確認は不可視ピクセルの URL で渡される場合があります。 広告の一部としてレンダリングされます
  4. サーバーでは、アプリケーションがウェブセーフな base64 で落札価格をデコードします。 その結果を復号します。

依存関係

次のような SHA-1 HMAC をサポートする暗号ライブラリが必要です。 OpenSSL

サンプルコード

サンプル コードは Java と C++ で用意されており、privatedatacommunicationprotocol からダウンロードできます。 プロジェクトです。

  • Java サンプルコードでは、Apache Commons Project をご覧ください。Apache Commons コードをダウンロードする必要はありません。 リファレンス実装に必要な部分が含まれているため、 自己完結型です

  • C++ サンプルコードでは、OpenSSL base64 BIO メソッドをご覧ください。ウェブセーフの Base64 でエンコードされた文字列(RFC 3548)を取得し、デコードします。 通常、ウェブセーフの base64 文字列は "="「.」のパディング(ただし、 引用符は読みやすくするために追加されており、 マクロ置換によって暗号化された料金は上乗せされません。「 リファレンス実装ではパディングが追加されます。これは、OpenSSL では パディングされていない文字列です。

エンコード

落札価格の暗号化と復号には 2 つのシークレットが必要ですが、 できます。完全性鍵と暗号鍵(i_keye_key です。どちらの鍵も、アカウント設定時に ウェブセーフの Base64 文字列(認定バイヤーのページにあります) [入札者(ビッダー)] 設定 >RTB 設定 >暗号鍵

完全性と暗号鍵の例:

skU7Ax_NL5pPAFyKdkfZjZz2-VhIN8bjj1rVFOaJ_5o=  // Encryption key (e_key)
arO23ykdNqUQ5LEoQ0FVmPkBd7xB5CO89PDZlSjpFxo=  // Integrity key (i_key)

鍵はウェブセーフにデコードし、ニュース メディア側で base64 でデコードする必要があります アプリケーション:

e_key = WebSafeBase64Decode('skU7Ax_NL5pPAFyKdkfZjZz2-VhIN8bjj1rVFOaJ_5o=')
i_key = WebSafeBase64Decode('arO23ykdNqUQ5LEoQ0FVmPkBd7xB5CO89PDZlSjpFxo=')

暗号化スキーム

価格は、カスタム暗号化スキームで暗号化されます。 適切なセキュリティを確保しながら、サイズのオーバーヘッドを最小限に抑えます。暗号化スキーム 鍵付き HMAC アルゴリズムを使用して、一意のキーに基づいてシークレット パッドを生成します。 あります。

暗号化料金は 28 バイトの固定長です。これは、 16 バイトの初期化ベクトル、8 バイトの暗号テキスト、4 バイトの整合性 できます。暗号化料金は、RFC に従ってウェブセーフの Base64 エンコード 3548 の形式にする必要があります(パディング文字は省略)。したがって、暗号化された 28 バイトの価格は、 勝者に関係なく、38 文字のウェブセーフ Base-64 文字列としてエンコード 支払う必要があります。

暗号化された料金の例:

YWJjMTIzZGVmNDU2Z2hpN7fhCuPemCce_6msaw  // 100 CPI micros
YWJjMTIzZGVmNDU2Z2hpN7fhCuPemCAWJRxOgA  // 1900 CPI micros
YWJjMTIzZGVmNDU2Z2hpN7fhCuPemC32prpWWw  // 2700 CPI micros

暗号化形式は次のとおりです。

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

価格は <price xor HMAC(encryption_key, initialization_vector)> として暗号化されるため、復号によって計算されます HMAC(encryption_key,initialization_vector) と XOR を 暗号化の料金を支払います。整合性ステージには 4 バイトの <HMAC(integrity_key, price||initialization_vector)> ここで || は連結です。

入力
iv 初期化ベクトル(16 バイト - インプレッションに固有)
e_key 暗号鍵(32 バイト - アカウント設定時に提供)
i_key 完全性キー(32 バイト - アカウント設定時に提供)
price (8 バイト - アカウントの通貨のマイクロ単位)
Notation
hmac(k, d) データ d の SHA-1 HMAC(キー k を使用)
a || b 文字列 b と連結された文字列 a
擬似コード
pad = hmac(e_key, iv)  // first 8 bytes
enc_price = pad <xor> price
signature = hmac(i_key, price || iv)  // first 4 bytes

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

復号スキーム

復号コードは、暗号鍵を使用して料金を復号する必要があります。 完全性キーで完全性ビットを検証します鍵は Cloud Storage バケットに 表示されます。この方法の詳細に制限はありません。 理解することが重要です。ほとんどの場合、 サンプルコードを修正し、ニーズに合わせて調整します。

入力
e_key 暗号鍵、32 バイト - アカウント設定時に提供
i_key 完全性キー、32 バイト - アカウント設定時に提供される
final_message 38 文字(ウェブセーフ Base64 エンコード)
擬似コード
// Base64 padding characters are omitted.
// Add any required base64 padding (= or ==).
final_message_valid_base64 = AddBase64Padding(final_message)

// Web-safe decode, then base64 decode.
enc_price = WebSafeBase64Decode(final_message_valid_base64)

// Message is decoded but remains encrypted.
(iv, p, sig) = enc_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);

Java ライブラリ

エンコード / デコードに暗号アルゴリズムを実装する代わりに、 決定するには、代わりに DoubleClickCrypto.java.詳細については、次をご覧ください: 暗号化