Jika penayang meneruskan data lokasi seluler ke Authorized Buyers yang lebih spesifik
daripada kode pos, Authorized Buyers akan mengirimkan 'hyperlocal'pembatasan wilayah kepada pembeli dalam
kolom terenkripsi baru: BidRequest.encrypted_hyperlocal_set
.
Linimasa
- Pengguna menginstal aplikasi seluler yang didukung iklan dan mengizinkan aplikasi mengakses dan membagikan lokasi perangkat kepada pihak ketiga. Aplikasi ini juga terintegrasi dengan Google Ads SDK dan mengirimkan lokasi perangkat ini ke Google.
- Server Google membuat sinyal penargetan hiperlokal khusus yang mewakili pembatasan wilayah di sekitar lokasi perangkat, seperti untuk melindungi privasi pengguna.
- Server Google melakukan serialisasi dan enkripsi sinyal penargetan hiperlokal menggunakan kunci keamanan khusus untuk setiap pembeli. Perhatikan bahwa bidder Anda bergantung pada kunci yang sama untuk mendekripsi makro WINNING_PRICE.
- Bidder mendekripsi dan membatalkan serialisasi sinyal penargetan hiperlokal ke dalam buffering protokol. Bidder Anda selanjutnya dapat menganalisis sinyal dan bid yang sesuai.
Dependensi
Anda memerlukan library kripto yang mendukung HMAC SHA-1, seperti Openssl.
Definisi
Sinyal penargetan hiperlokal didefinisikan dalam proto seperti ini:
// A hyperlocal targeting location when available. // message Hyperlocal { // A location on the Earth's surface. // message Point { optional float latitude = 1; optional float longitude = 2; } // The mobile device can be at any point inside the geofence polygon defined // by a list of corners. Currently, the polygon is always a parallelogram // with 4 corners. repeated Point corners = 1; } message HyperlocalSet { // This field currently contains at most one hyperlocal polygon. repeated Hyperlocal hyperlocal = 1; // The approximate geometric center of the geofence area. It is calculated // exclusively based on the geometric shape of the geofence area and in no // way indicates the mobile device's actual location within the geofence // area. If multiple hyperlocal polygons are specified above then // center_point is the geometric center of all hyperlocal polygons. optional Hyperlocal.Point center_point = 2; } // Hyperlocal targeting signal when available, encrypted as described at // https://developers.google.com/authorized-buyers/rtb/response-guide/decrypt-hyperlocal optional bytes encrypted_hyperlocal_set = 40;
Setiap sinyal penargetan hiperlokal berisi satu atau beberapa poligon dan satu titik tengah. Untuk setiap poligon, sinyal penargetan hiperlokal berisi:
- Lintang dan bujur setiap sudut poligon secara berurutan, diteruskan sebagai kolom
corners
berulang. - Perkiraan pusat geometris area pembatasan wilayah, yang diteruskan dalam kolom
center_point
opsional.
Struktur sinyal penargetan
Sinyal penargetan hiperlokal terenkripsi yang terdapat di
BidRequest.encrypted_hyperlocal_set
berisi 3 bagian:
initialization_vector
: 16 byte.ciphertext
: rangkaian bagian 20 byte.integrity_signature
: 4 byte.
{initialization_vector (16 bytes)}{ciphertext (20-byte sections)}{integrity_signature (4 bytes)}
Array byte ciphertext
dibagi menjadi beberapa bagian
20 byte, dengan pengecualian bahwa bagian terakhir dapat berisi antara 1
dan 20 byte inklusif. Untuk setiap bagian byte_array
asli, ciphertext
20 byte yang sesuai dihasilkan
sebagai:
<byte_array <xor> HMAC(encryption_key, initialization_vector || counter_bytes)>
Dengan ||
merupakan penyambungan.
Definisi
Variabel | Detail |
---|---|
initialization_vector |
16 byte - unik untuk tayangan. |
encryption_key |
32 byte - diberikan saat pembuatan akun. |
integrity_key |
32 byte - diberikan saat pembuatan akun. |
byte_array |
Objek HyperlocalSet yang diserialisasi, dalam bagian 20 byte. |
counter_bytes |
Nilai byte yang menunjukkan nomor ordinal bagian, lihat di bawah ini. |
final_message |
Array byte yang dikirim melalui kolom BidRequest.encrypted_hyperlocal_set . |
Operator | Detail |
---|---|
hmac(key, data) |
HMAC SHA-1, menggunakan key untuk mengenkripsi data . |
a || b |
string a disambungkan dengan string b . |
Menghitung penghitung_byte
counter_bytes
menandai urutan setiap bagian 20 byte
dari ciphertext
. Perhatikan bahwa bagian terakhir dapat berisi antara 1 dan 20 byte inklusif. Untuk mengisi counter_bytes
dengan nilai yang benar saat menjalankan fungsi hmac()
, hitung bagian 20 byte (termasuk sisanya) dan gunakan tabel referensi berikut:
Nomor bagian | Nilai counter_bytes |
---|---|
0 | None |
1 ... 256 | 1 byte. Nilai ini meningkat dari 0 hingga 255 secara berurutan. |
257 ... 512 | 2 byte. Nilai byte pertama adalah 0, nilai byte kedua meningkat dari 0 menjadi 255 secara berurutan. |
513 ... 768 | 3 byte. Nilai dua byte pertama adalah 0, nilai byte terakhir bertambah dari 0 hingga 255 secara berurutan. |
Kami tidak memperkirakan panjang
BidRequest.encrypted_hyperlocal_set
melebihi satu kilobyte, bahkan
memperhitungkan pertumbuhan lebih lanjut. Meskipun demikian,
counter_bytes
dapat sepanjang diperlukan untuk mendukung sinyal penargetan hiperlokal dengan panjang arbitrer.
Skema enkripsi
Skema enkripsi untuk sinyal penargetan hiperlokal didasarkan pada skema yang sama dengan yang digunakan untuk mendekripsi konfirmasi harga.
Serialisasi: Sinyal penargetan hiperlokal, yang merupakan instance objek HyperlocalSet seperti yang ditentukan dalam proto, pertama kali diserialisasi melalui
SerializeAsString()
ke array byte.Enkripsi: Array byte kemudian dienkripsi menggunakan skema enkripsi kustom yang dirancang untuk meminimalkan overhead ukuran sambil memastikan keamanan yang memadai. Skema enkripsi menggunakan algoritme HMAC yang dikunci untuk menghasilkan pad rahasia berdasarkan
initialization_vector
, yang unik untuk peristiwa tayangan.
Kode semu enkripsi
byte_array = SerializeAsString(HyperlocalSet object) pad = hmac(encryption_key, initialization_vector || counter_bytes ) // for each 20-byte section of byte_array ciphertext = pad <xor> byte_array // for each 20-byte section of byte_array integrity_signature = hmac(integrity_key, byte_array || initialization_vector) // first 4 bytes final_message = initialization_vector || ciphertext || integrity_signature
Skema dekripsi
Kode dekripsi Anda harus 1) mendekripsi sinyal penargetan hiperlokal menggunakan kunci enkripsi, dan 2) memverifikasi bit integritas dengan kunci integritas. Kunci akan diberikan kepada Anda selama penyiapan akun. Tidak ada pembatasan terhadap cara Anda membuat struktur penerapan. Pada umumnya, Anda harus dapat mengambil kode contoh dan menyesuaikannya dengan kebutuhan Anda.
- Buat bantalan:
HMAC(encryption_key, initialization_vector || counter_bytes)
- XOR: Ambil hasil ini dan
<xor>
dengan ciphertext untuk membalikkan enkripsi. - Verifikasi: Tanda tangan integritas meneruskan
4 byte dari
HMAC(integrity_key, byte_array || initialization_vector)
Kode semu dekripsi
(initialization_vector, ciphertext, integrity_signature) = final_message // split up according to length rules pad = hmac(encryption_key, initialization_vector || counter_bytes) // for each 20-byte section of ciphertext byte_array = ciphertext <xor> pad // for each 20-byte section of ciphertext confirmation_signature = hmac(integrity_key, byte_array || initialization_vector) success = (confirmation_signature == integrity_signature)
Contoh kode C++
Berikut adalah fungsi utama dari kode contoh dekripsi lengkap kami.
bool DecryptByteArray( const string& ciphertext, const string& encryption_key, const string& integrity_key, string* cleartext) { // Step 1. find the length of initialization vector and clear text. const int cleartext_length = ciphertext.size() - kInitializationVectorSize - kSignatureSize; if (cleartext_length < 0) { // The length cannot be correct. return false; } string iv(ciphertext, 0, kInitializationVectorSize); // Step 2. recover clear text cleartext->resize(cleartext_length, '\0'); const char* ciphertext_begin = string_as_array(ciphertext) + iv.size(); const char* const ciphertext_end = ciphertext_begin + cleartext->size(); string::iterator cleartext_begin = cleartext->begin(); bool add_iv_counter_byte = true; while (ciphertext_begin < ciphertext_end) { uint32 pad_size = kHashOutputSize; uchar encryption_pad[kHashOutputSize]; if (!HMAC(EVP_sha1(), string_as_array(encryption_key), encryption_key.length(), (uchar*)string_as_array(iv), iv.size(), encryption_pad, &pad_size)) { printf("Error: encryption HMAC failed.\n"); return false; } for (int i = 0; i < kBlockSize && ciphertext_begin < ciphertext_end; ++i, ++cleartext_begin, ++ciphertext_begin) { *cleartext_begin = *ciphertext_begin ^ encryption_pad[i]; } if (!add_iv_counter_byte) { char& last_byte = *iv.rbegin(); ++last_byte; if (last_byte == '\0') { add_iv_counter_byte = true; } } if (add_iv_counter_byte) { add_iv_counter_byte = false; iv.push_back('\0'); } } }
Contoh sinyal dan kunci hiperlokal
Untuk menguji dan memverifikasi kode Anda:
- Konversikan string yang berisi 308 karakter hex menjadi array 154 byte. Misalnya, dengan string berikut:
E2014EA201246E6F6E636520736F7572636501414243C0ADF6B9B6AC17DA218FB50331EDB376701309CAAA01246E6F6E636520736F7572636501414243C09ED4ECF2DB7143A9341FDEFD125D96844E25C3C202466E6F6E636520736F7572636502414243517C16BAFADCFAB841DE3A8C617B2F20A1FB7F9EA3A3600256D68151C093C793B0116DB3D0B8BE9709304134EC9235A026844F276797
konversikan menjadi array 154 byte sebagai berikut:const char serialized_result[154] = { 0xE2, 0x01, 0x4E, ... };
- Panggil metode
BidRequest.ParsePartialFromString()
untuk melakukan deserialisasi array 154 byte ke buffering protokolBidRequest
.BidRequest bid_req; bid_req.ParsePartialFromString(serialzed_result);
- Pastikan bahwa
BidRequest
hanya memiliki 3 kolom:encrypted_hyperlocal_set
Dideklarasikan di dalam pesanBidReqeust
.encrypted_advertising_id
Dideklarasikan di dalam pesanBidReqeust.Mobile
.encrypted_hashed_idfa
Dideklarasikan di dalam pesanBidReqeust.Mobile
.
Contoh:
encrypted_hyperlocal_set:( { 100, 100 }, { 200, -300 }, { -400, 500 }, { -600, -700 },) encrypted_advertising_id: { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 } encrypted_hashed_idfa : { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xF1 }
- Gunakan
encryption_key
danintegrity_key
berikut untuk mendekripsi 3 kolom dan verifikasi bahwa Anda mendekripsinya dengan benar.encryption_key = {0x02, 0xEE, 0xa8, 0x3c, 0x6c, 0x12, 0x11, 0xe1, 0x0b, 0x9f, 0x88, 0x96, 0x6c, 0xee, 0xc3, 0x49, 0x08, 0xeb, 0x94, 0x6f, 0x7e, 0xd6, 0xe4, 0x41, 0xaf, 0x42, 0xb3, 0xc0, 0xf3, 0x21, 0x81, 0x40}; integrity_key = {0xbf, 0xFF, 0xec, 0x55, 0xc3, 0x01, 0x30, 0xc1, 0xd8, 0xcd, 0x18, 0x62, 0xed, 0x2a, 0x4c, 0xd2, 0xc7, 0x6a, 0xc3, 0x3b, 0xc0, 0xc4, 0xce, 0x8a, 0x3d, 0x3b, 0xbd, 0x3a, 0xd5, 0x68, 0x77, 0x92};
Mendeteksi serangan respons yang usang
Untuk mendeteksi serangan respons usang, sebaiknya filter respons dengan stempel waktu yang berbeda secara signifikan dari waktu sistem, setelah memperhitungkan perbedaan zona waktu. Server kami disetel ke waktu PST/PDT.
Untuk mengetahui detail implementasi, lihat “Mendeteksi Serangan Respons yang Basi” di artikel Mendekripsi Informasi Harga.
Library Java
Daripada menerapkan algoritme kripto untuk mengenkode dan mendekode sinyal penargetan hiperlokal, Anda dapat menggunakan DoubleClickCrypto.java. Untuk informasi selengkapnya, lihat Kriptografi.