解密價格確認

當您的廣告素材贏得競價時,Google 可告知您勝出組合 「價格」是廣告素材包含相關巨集時的價格。

如果您的出價工具設定為使用 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 的曝光網址中:

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

情境

  1. 您的 OpenRTB 出價應用程式包含 ${AUCTION_PRICE} 巨集。
  2. 在無填充的網路安全中,Google 將巨集代換成得標的價格 Base64 編碼 (RFC 3548)。
  3. 程式碼片段會以您選定的格式傳送確認訊息。適用對象 例如,此確認可能會在隱藏像素的網址中傳送 請求並顯示在廣告中。
  4. 在伺服器上,應用程式網路安全 base64 會將得標價格解碼 並將結果解密。

依附元件

您需要支援 SHA-1 HMAC 的加密編譯程式庫,例如 Openssl。

程式碼範例

程式碼範例是以 Java 和 C++ 提供,可從 privatedatacommunicationprotocol 下載 專案

  • Java 程式碼範例會使用 Apache 的 Base64 解碼器 共用專案您不必下載 Apache Commons 程式碼 因為參考實作包含必要的部分 獨立作業

  • C++ 程式碼範例會使用 OpenSSL Base64 BIO 方法。並擷取以網路安全 base64 編碼的字串 (RFC 3548)。 通常,網路安全 base64 字串會取代「=」邊框間距加上「.」(請注意, 為求閱讀方便,我們在引號中加入了引號,但這並未包含在 但替代巨集不會填入加密的價格。 參考實作會新增邊框間距,因為 OpenSSL 發生問題 未填充的字串。

編碼

得標價格加密與解密需要兩組密鑰,但彼此的共用 鍵。完整性金鑰和加密金鑰,稱為 i_key。 和 e_key。這兩個金鑰會在帳戶設定時提供 網頁安全 Base64 字串,位於 Authorized Buyers 頁面 設定 >即時出價設定 >加密金鑰

完整性和加密金鑰範例:

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 演算法,依據 曝光事件 ID

加密價格的固定長度為 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 字串 a 與字串 b 串連
虛擬程式碼
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 )

解密機制

您的解密程式碼必須使用加密金鑰解密價格。 並使用完整性金鑰驗證完整性位元。金鑰會提供給 設定流程 建構實作項目絕大部分的情況下,您應該能夠 並視需求進行調整

輸入
e_key 加密金鑰 (32 個位元組)
i_key 完整性金鑰 (32 位元組,在建立帳戶時提供給使用者)
final_message 使用網路安全 base64 編碼的 38 個字元
虛擬程式碼
// 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.若需更多資訊,請參閲 密碼學