Saat materi iklan Anda memenangkan lelang, Google dapat memberi tahu Anda harga
pemenang jika materi iklan menyertakan makro ${AUCTION_PRICE}
.
Saat diperluas, makro akan menampilkan harga pemenang dalam bentuk terenkripsi. Piksel ini 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 dalam URL tayangan di VAST:
https://example.com/vast/v?price=${AUCTION_PRICE}
Skenario
- Aplikasi bidding OpenRTB Anda menyertakan makro
${AUCTION_PRICE}
dalam cuplikan HTML atau URL VAST yang ditampilkan ke Google. - Google mengganti harga pemenang untuk makro dalam encoding base64 yang aman bagi web tanpa padding (RFC 3548).
- Cuplikan meneruskan konfirmasi dalam format yang telah Anda pilih. Misalnya, konfirmasi mungkin diteruskan di URL permintaan piksel yang tidak terlihat yang dirender sebagai bagian dari iklan.
- Di server, base64 aman web aplikasi Anda mendekode informasi harga pemenang dan mendekripsi hasilnya.
Dependensi
Anda memerlukan library kripto yang mendukung SHA-1 HMAC, seperti Openssl.
Kode contoh
Kode contoh disediakan dalam Java dan C++ dan dapat didownload dari project privatedatacommunicationprotocol.
Kode contoh Java menggunakan dekoder base64 dari project Apache commons. Anda tidak perlu mendownload kode Apache commons, karena implementasi referensi menyertakan bagian yang diperlukan sehingga bersifat mandiri.
Kode contoh C++ menggunakan metode BIO base64 OpenSSL. Fungsi ini mengambil string yang dienkode base64 yang sesuai untuk web (RFC 3548) dan mendekodenya. Biasanya, string base64 yang aman untuk web mengganti padding "=" dengan "." (perhatikan bahwa tanda kutip ditambahkan untuk kejelasan pembacaan dan tidak disertakan dalam protokol), tetapi penggantian makro tidak mengisi harga terenkripsi. Implementasi referensi menambahkan padding karena OpenSSL mengalami masalah dengan string tanpa padding.
Encoding
Enkripsi dan dekripsi harga pemenang memerlukan dua kunci rahasia, tetapi bersama. Kunci integritas, dan kunci enkripsi, masing-masing disebut sebagai i_key
,
dan e_key
. Kedua kunci tersebut diberikan saat penyiapan akun sebagai
string base64 yang aman untuk web, dan dapat ditemukan di halaman Authorized Buyers
di bagian Setelan
bidder > Setelan RTB > Kunci enkripsi.
Contoh kunci integritas dan enkripsi:
skU7Ax_NL5pPAFyKdkfZjZz2-VhIN8bjj1rVFOaJ_5o= // Encryption key (e_key) arO23ykdNqUQ5LEoQ0FVmPkBd7xB5CO89PDZlSjpFxo= // Integrity key (i_key)
Kunci harus didekode dengan aman untuk web, lalu didekode base64 oleh aplikasi Anda:
e_key = WebSafeBase64Decode('skU7Ax_NL5pPAFyKdkfZjZz2-VhIN8bjj1rVFOaJ_5o=') i_key = WebSafeBase64Decode('arO23ykdNqUQ5LEoQ0FVmPkBd7xB5CO89PDZlSjpFxo=')
Skema enkripsi
Harga dienkripsi menggunakan skema enkripsi kustom yang dirancang untuk meminimalkan overhead ukuran sekaligus memastikan keamanan yang memadai. Skema enkripsi menggunakan algoritma HMAC dengan kunci untuk menghasilkan secret pad berdasarkan ID peristiwa tayangan iklan yang unik.
Harga terenkripsi memiliki panjang tetap 28 byte. Ini terdiri dari vektor inisialisasi 16 byte, 8 byte ciphertext, dan tanda tangan integritas 4 byte. Harga terenkripsi dienkode dalam base64 yang sesuai untuk web, sesuai dengan RFC 3548, dengan karakter padding dihilangkan. Dengan demikian, harga terenkripsi 28 byte dienkode sebagai string base-64 38 karakter yang aman bagi web, terlepas dari harga pemenang yang dibayar.
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 memerlukan 4 byte
<HMAC(integrity_key, price||initialization_vector)>
dengan
||
adalah penyambungan.
Input | |
---|---|
iv |
initialization vector (16 byte - unik untuk tayangan) |
e_key |
kunci enkripsi (32 byte - diberikan saat penyiapan akun) |
i_key |
kunci integritas (32 byte - diberikan saat penyiapan akun) |
price |
(8 byte - dalam mikro mata uang akun) |
Notasi | |
hmac(k, d) |
HMAC SHA-1 data d , menggunakan kunci k |
a || b |
string a yang digabungkan 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 Anda harus mendekripsi harga menggunakan kunci enkripsi, dan memverifikasi bit integritas dengan kunci integritas. Kunci akan diberikan kepada Anda selama penyiapan. Tidak ada batasan pada detail cara Anda menstrukturkan penerapan. Pada umumnya, Anda dapat mengambil kode contoh dan menyesuaikannya sesuai kebutuhan.
Input | |
---|---|
e_key |
kunci enkripsi, 32 byte - diberikan saat penyiapan akun |
i_key |
kunci integritas, 32 byte - diberikan saat penyiapan akun |
final_message |
38 karakter yang dienkode dalam base64 yang sesuai untuk 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 serangan replay atau respons yang sudah tidak berlaku, sebaiknya Anda memfilter respons dengan stempel waktu yang berbeda secara signifikan dengan waktu sistem, setelah memperhitungkan perbedaan zona waktu.
Vektor inisialisasi berisi stempel waktu dalam 8 byte pertama. File 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++ berikut:
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
Daripada menerapkan algoritma kripto untuk mengenkode dan mendekode harga pemenang, Anda dapat menggunakan DoubleClickCrypto.java. Untuk mengetahui informasi selengkapnya, lihat Kriptografi.