Jaringan Iklan yang menggunakan
tag JavaScript untuk mengisi iklan melalui Authorized Buyers memenuhi syarat untuk
menerima ID pengiklan untuk perangkat Android dan iOS.
Informasi ini dikirim melalui makro %%EXTRA_TAG_DATA%%
atau
%%ADVERTISING_IDENTIFIER%%
di tag JavaScript yang dikelola
oleh Authorized Buyers. Bagian lainnya berfokus pada ekstraksi
%%EXTRA_TAG_DATA%%
, tetapi lihat
Pemasaran ulang dengan IDFA atau ID Iklan untuk detail
tentang buffering proto terenkripsi %%ADVERTISING_IDENTIFIER%%
MobileAdvertisingId
yang dapat didekripsi secara analog.
Rentang waktu
- Jaringan Iklan memperbarui tag dalam aplikasi JavaScript-nya
melalui UI Authorized Buyers,
dengan menambahkan makro
%%EXTRA_TAG_DATA%%
seperti yang dijelaskan di bawah. - Pada waktu penayangan, aplikasi akan meminta iklan dari Authorized Buyers melalui Google Mobile Ads SDK, sekaligus meneruskan ID pengiklan dengan aman.
- Aplikasi akan menerima kembali tag JavaScript, dengan makro
%%EXTRA_TAG_DATA%%
yang diisi dengan buffering protokol Jaringan Iklan terenkripsi yang berisi ID tersebut. - Aplikasi menjalankan tag ini, sehingga melakukan panggilan ke Jaringan Iklan untuk iklan pemenang.
- Untuk menggunakan (memonetisasi) informasi ini, Jaringan Iklan harus memproses buffering protokol:
- Dekode string websafe kembali menjadi bytestring dengan WebSafeBase64.
- Dekripsinya menggunakan skema yang diuraikan di bawah ini.
- Lakukan deserialisasi proto dan dapatkan ID pengiklan dari ExtraTagData.advertising_id atau ExtraTagData.hashed_idfa.
Dependensi
- WebSafeBase64 encoder.
- Library kripto yang mendukung HMAC SHA-1, seperti Openssl.
- Compiler buffer protokol Google.
Mendekode string websafe
Karena informasi yang dikirim melalui makro %%EXTRA_TAG_DATA%%
harus dikirim melalui URL, server Google mengenkodenya dengan base64 yang aman untuk web (RFC 3548).
Oleh karena itu, sebelum mencoba dekripsi, Anda harus mendekode karakter ASCII kembali ke bytestring. Contoh kode C++ di bawah ini didasarkan pada BIO_f_base64() Project OpenSSL, dan merupakan bagian dari kode dekripsi contoh Google.
string AddPadding(const string& b64_string) { if (b64_string.size() % 4 == 3) { return b64_string + "="; } else if (b64_string.size() % 4 == 2) { return b64_string + "=="; } return b64_string; } // Adapted from http://www.openssl.org/docs/man1.1.0/crypto/BIO_f_base64.html // Takes a web safe base64 encoded string (RFC 3548) and decodes it. // Normally, web safe base64 strings have padding '=' replaced with '.', // but we will not pad the ciphertext. We add padding here because // openssl has trouble with unpadded strings. string B64Decode(const string& encoded) { string padded = AddPadding(encoded); // convert from web safe -> normal base64. int32 index = -1; while ((index = padded.find_first_of('-', index + 1)) != string::npos) { padded[index] = '+'; } index = -1; while ((index = padded.find_first_of('_', index + 1)) != string::npos) { padded[index] = '/'; } // base64 decode using openssl library. const int32 kOutputBufferSize = 256; char output[kOutputBufferSize]; BIO* b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); BIO* bio = BIO_new_mem_buf(const_cast(padded.data()), padded.length()); bio = BIO_push(b64, bio); int32 out_length = BIO_read(bio, output, kOutputBufferSize); BIO_free_all(bio); return string(output, out_length); }
Struktur bytestring terenkripsi
Setelah mendekode karakter ASCII kembali menjadi string byte, Anda siap untuk mendekripsinya. Bytestring terenkripsi berisi 3 bagian:
initialization_vector
: 16 byte.ciphertext
: serangkaian bagian yang berukuran 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 secara inklusif. Untuk setiap bagian byte_array
asli, ciphertext
20 byte
yang sesuai akan dihasilkan sebagai:
<byte_array <xor> HMAC(encryption_key, initialization_vector || counter_bytes)>
dengan ||
adalah penyambungan.
Definisi
Variabel | Detail |
---|---|
initialization_vector |
16 byte - unik untuk tayangan. |
encryption_key |
32 byte - disediakan saat pembuatan akun. |
integrity_key |
32 byte - disediakan saat pembuatan akun. |
byte_array |
Objek ExtraTagData serial, dalam bagian 20 byte. |
counter_bytes |
Nilai byte yang menunjukkan nomor ordinal bagian, lihat di bawah. |
final_message |
Total array byte yang dikirim melalui makro %%EXTRA_TAG_DATA%% (dikurangi encoding WebSafeBase64). |
Operator | Detail |
---|---|
hmac(key, data) |
HMAC SHA-1, menggunakan key untuk mengenkripsi data . |
a || b |
string a yang 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 | Tidak ada |
1 ... 256 | 1 byte. Nilai bertambah dari 0 hingga 255 secara berurutan. |
257 ... 512 | 2 byte. Nilai byte pertama adalah 0. Nilai byte kedua bertambah dari 0 hingga 255 secara berurutan. |
513 ... 768 | 3 byte. Nilai dua byte pertama adalah 0, nilai byte terakhir meningkat dari 0 hingga 255 secara berurutan. |
Skema enkripsi
Skema enkripsi didasarkan pada skema yang sama yang digunakan untuk mendekripsi sinyal penargetan hyperlocal.
Serialisasi: Instance objek ExtraTagData seperti yang ditentukan dalam buffering protokol akan diserialisasi terlebih dahulu melalui
SerializeAsString()
ke array byte.Enkripsi: Array byte kemudian 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 pad rahasia berdasarkan
initialization_vector
, yang unik untuk peristiwa tayangan.
Kode semu enkripsi
byte_array = SerializeAsString(ExtraTagData 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 buffering protokol menggunakan kunci enkripsi, dan 2) memverifikasi bit integritas dengan kunci integritas. Kunci akan diberikan kepada Anda selama pembuatan akun. Tidak ada batasan pada cara Anda menyusun implementasi. Secara umum, Anda harus dapat mengambil kode contoh dan menyesuaikannya sesuai dengan kebutuhan.
- Membuat pad Anda:
HMAC(encryption_key, initialization_vector || counter_bytes)
- XOR: Ambil hasil ini dan
<xor>
dengan teks cipher untuk membalikkan enkripsi. - Memverifikasi: Tanda tangan integritas meneruskan 4 byte
HMAC(integrity_key, byte_array || initialization_vector)
Kode semu dekripsi
// split up according to length rules (initialization_vector, ciphertext, integrity_signature) = final_message // for each 20-byte section of ciphertext pad = hmac(encryption_key, initialization_vector || counter_bytes) // for each 20-byte section of ciphertext byte_array = ciphertext <xor> pad confirmation_signature = hmac(integrity_key, byte_array || initialization_vector) success = (confirmation_signature == integrity_signature)
Contoh kode C++
Fungsi kunci dari kode contoh dekripsi lengkap kami disertakan di sini.
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'); } }
Mendapatkan data dari buffering protokol Jaringan Iklan
Setelah mendekode dan mendekripsi data yang diteruskan di
%%EXTRA_TAG_DATA%%
, Anda siap mendeserialisasi buffering protokol
dan mendapatkan ID pengiklan untuk penargetan.
Jika Anda tidak terbiasa dengan buffering protokol, mulai dengan dokumentasi kami.
Definisi
Buffering protokol Jaringan Iklan kita didefinisikan seperti ini:
message ExtraTagData { // advertising_id can be Apple's identifier for advertising (IDFA) // or Android's advertising identifier. When the advertising_id is an IDFA, // it is the plaintext returned by iOS's [ASIdentifierManager // advertisingIdentifier]. For hashed_idfa, the plaintext is the MD5 hash of // the IDFA. Only one of the two fields will be available, depending on the // version of the SDK making the request. Later SDKs provide unhashed values. optional bytes advertising_id = 1; optional bytes hashed_idfa = 2; }
Anda harus melakukan deserialisasi menggunakan ParseFromString()
seperti yang dijelaskan dalam dokumentasi buffering protokol C++.
Untuk mengetahui detail tentang kolom advertising_id
Android dan iOS hashed_idfa
, lihat Mendekripsi ID Iklan dan Menargetkan inventaris aplikasi seluler dengan IDFA.
Library Java
Daripada menerapkan algoritma kripto untuk mengenkode dan mendekode ID Pengiklan untuk jaringan iklan, Anda dapat menggunakan DoubleClickCrypto.java. Untuk informasi selengkapnya, lihat Kriptografi.