Mendekripsi Informasi Harga

Saat materi iklan Anda memenangkan lelang, Google dapat memberi tahu Anda materi iklan yang menang adalah jika materi iklan menyertakan makro yang relevan.

Jika bidder Anda dikonfigurasi untuk menggunakan protokol OpenRTB, yang disertakan dengan bid Anda harus menggunakan ${AUCTION_PRICE} IAB makro.

Jika bidder Anda menggunakan protokol Google RTB yang tidak digunakan lagi, materi iklan harus menggunakan %%WINNING_PRICE%% Google makro.

Jika makro ini diperluas, makro akan mengembalikan harga pemenang dalam bentuk terenkripsi. Mereka dapat disertakan dalam materi iklan, misalnya, dengan permintaan piksel tidak terlihat yang dirender sebagai bagian dari iklan:

<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>

Makro ${AUCTION_PRICE} juga dapat disertakan dalam URL VAST materi iklan video, tetapi tidak di URL tayangan di VAST:

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

Skenario

  1. Permohonan bidding OpenRTB Anda mencakup ${AUCTION_PRICE} dalam cuplikan HTML atau URL VAST yang ditampilkannya ke Google.
  2. Google mengganti harga pemenang untuk makro di web-safe tanpa padding Encoding base64 (RFC 3548).
  3. Cuplikan ini meneruskan konfirmasi dalam format yang telah Anda pilih. Sebagai konfirmasi mungkin diteruskan dalam URL dari piksel yang tidak terlihat permintaan yang dirender sebagai bagian dari iklan.
  4. Di server, aplikasi Anda yang aman bagi web atau base64 mendekode harga pemenang informasi dan membongkar enkripsi hasilnya.

Dependensi

Anda akan membutuhkan perpustakaan kripto yang mendukung SHA-1 HMAC, seperti OpenSSL.

Kode contoh

Kode contoh disediakan dalam Java dan C++ serta dapat diunduh dari privatedatacommunicationprotocol project Anda.

  • Kode contoh Java menggunakan decoder base64 dari Apache project commons sendiri. Anda tidak perlu mengunduh kode Apache commons, karena penerapan referensi mencakup bagian yang diperlukan dan karenanya mandiri.

  • Kode contoh C++ menggunakan antarmuka OpenSSL metode BIO base64. Fungsi ini mengambil string berenkode base64 yang aman bagi web (RFC 3548) dan mendekodenya. Biasanya, string base64 yang aman bagi web menggantikan "=" padding dengan "." (perhatikan bahwa tanda kutip ditambahkan agar lebih jelas dan tidak disertakan dalam ), namun substitusi makro tidak menerapkan harga yang dienkripsi. Tujuan implementasi referensi menambahkan padding karena OpenSSL memiliki masalah string tanpa padding.

Encoding

Enkripsi dan dekripsi harga pemenang membutuhkan dua rahasia, tetapi dibagikan, tombol. Kunci integritas dan kunci enkripsi, yang disebut sebagai i_key, dan e_key masing-masing. Kedua kunci disediakan saat pembuatan akun sebagai string base64 yang aman bagi web, dan dapat ditemukan di halaman Authorized Buyers di bagian Bidder setelan > Setelan RTB > Kunci enkripsi.

Contoh kunci enkripsi dan integritas:

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

Kunci harus didekode dengan aman bagi web, lalu didekode dalam base64 oleh aplikasi:

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

Skema enkripsi

Harga dienkripsi menggunakan skema enkripsi khusus yang dirancang untuk meminimalkan overhead ukuran sekaligus memastikan keamanan yang memadai. Skema enkripsi menggunakan algoritma HMAC berkunci untuk menghasilkan pad rahasia berdasarkan ID peristiwa tayangan iklan.

Harga yang dienkripsi memiliki panjang tetap 28 byte. Aplikasi ini terdiri dari Vektor inisialisasi 16-byte, ciphertext 8 byte, dan integritas 4-byte tanda tangan. Harga terenkripsi berenkode base64 yang aman bagi web, sesuai dengan RFC 3548, dengan karakter padding dihilangkan. Dengan demikian, harga yang dienkripsi 28 byte adalah dienkode sebagai string base-64 yang aman bagi web berisi 38 karakter, terlepas dari dari harga yang dibayarkan.

Contoh harga terenkripsi:

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

Format terenkripsi adalah:

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

Harga dienkripsi sebagai <price xor HMAC(encryption_key, initialization_vector)> sehingga dekripsi menghitung HMAC(encryption_key,initialization_vector) dan xor dengan harga terenkripsi untuk membalikkan enkripsi. Tahap integritas mengambil 4 byte <HMAC(integrity_key, price||initialization_vector)> di mana || adalah penyambungan.

Input
iv vektor inisialisasi (16 byte - unik untuk tayangan)
e_key kunci enkripsi (32 byte - disediakan saat penyiapan akun)
i_key kunci integritas (32 byte - disediakan saat penyiapan akun)
price (8 byte - dalam mikro mata uang akun)
Notasi
hmac(k, d) HMAC data d SHA-1, menggunakan kunci k
a || b string a yang disambungkan dengan string b
Kode semu
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 )

Skema dekripsi

Kode dekripsi harus mendekripsi harga menggunakan kunci enkripsi, dan memverifikasi bit integritas dengan kunci integritas. Kunci tersebut akan diberikan kepada Anda selama penyiapan. Tidak ada batasan tentang bagaimana cara Anda menyusun implementasi Anda. Secara keseluruhan, Anda harus bisa melakukan kode contoh dan menyesuaikannya sesuai dengan kebutuhan Anda.

Input
e_key kunci enkripsi, 32 byte - disediakan saat penyiapan akun
i_key kunci integritas, 32 byte - disediakan saat penyiapan akun
final_message 38 karakter dienkode dengan base64 yang aman bagi web
Kode semu
// 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)

Mendeteksi serangan respons yang sudah tidak berlaku

Untuk mendeteksi respons yang basi, atau mengulangi, serangan, sebaiknya Anda memfilter respons dengan stempel waktu yang sangat berbeda dari sistem setelah memperhitungkan perbedaan zona waktu.

Vektor inisialisasi berisi stempel waktu dalam 8 byte pertama. Teknologi ini dapat dibaca oleh fungsi C++ berikut:

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)
}

Stempel waktu dapat dikonversi ke bentuk yang dapat dibaca manusia menggunakan Kode 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);

Library Java

Alih-alih menerapkan algoritma kripto untuk mengenkode dan mendekode harga yang unggul, Anda dapat menggunakan DoubleClickCrypto.java. Untuk informasi selengkapnya, lihat Kriptografi.